XML 排序/格式化工具
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1424029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
XML sorting/formatting tool
提问by Andrey Adamovich
Is there any tool that can (pretty-print) format XML file as well as sort both its elements and attributes?
是否有任何工具可以(漂亮地打印)格式化 XML 文件以及对其元素和属性进行排序?
采纳答案by Andrey Adamovich
I have found this post: http://www.biglist.com/lists/xsl-list/archives/200106/msg01225.htmlthat uses the following XSLT to indent XML and also sort attributes:
我找到了这篇文章:http: //www.biglist.com/lists/xsl-list/archives/200106/msg01225.html,它使用以下 XSLT 来缩进 XML 并对属性进行排序:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<!-- Sort the attributes by name. -->
<xsl:for-each select="@*">
<xsl:sort select="name( . )"/>
<xsl:copy/>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()|comment()|processing-instruction()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
I haven't tried it yet, but most likely I will stick to XSLT to do formatting for me.
我还没有尝试过,但很可能我会坚持使用 XSLT 为我进行格式化。
回答by Akira Yamamoto
I liked this tool: https://xmlsorter.codeplex.com/
我喜欢这个工具:https: //xmlsorter.codeplex.com/
You can sort by tag name and attributes. I like to use it before comparing some XML files.
您可以按标签名称和属性进行排序。我喜欢在比较一些 XML 文件之前使用它。


回答by wasatchwizard
I was looking for a similar utility and didn't really find what I was looking for, so I just barely wrote one instead. It's very simple (and doesn't include attributes in node sorting), but works.
我正在寻找类似的实用程序,但并没有真正找到我想要的东西,所以我只是勉强写了一个。它非常简单(并且不包括节点排序中的属性),但有效。
Maybe it'll be useful to others.. It's on GitHub.
也许它对其他人有用.. 它在GitHub 上。
Here's a bit from the GitHub page...
这是GitHub页面上的一些内容......
USAGE: sortxml.exe [options] infile [outfile]
infile The name of the file to sort, etc.
outfile The name of the file to save the output to.
If this is omitted, then the output is written to stdout.
OPTIONS:
--pretty Ignores the input formatting and makes the output look nice.
--sort Sort both the nodes and attributes.
--sortnode Sort the nodes.
--sortattr Sort the attributes.
(prefix an option with ! to turn it off.)
The default is to output pretty and sorted nodes and attributes. Here is an example:
默认是输出漂亮和排序的节点和属性。下面是一个例子:
> type sample.xml
<?xml version="1.0" encoding="utf-8" ?><root><node value="one" attr="name"/></root>
> sortxml.exe sample.xml
<?xml version="1.0" encoding="utf-8"?>
<root>
<node attr="name" value="one" />
</root>
回答by Yahoo Serious
Out of frustration with Visual Studio which seems to reorder & rewrite EDMX-files (Entity Framework) all the time (see also this Uservoice), I wrote some Linqpad-code to reorder stuff. It is is however easy (and obvious) to use outside of LinqPad.
出于对 Visual Studio 似乎一直在重新排序和重写 EDMX 文件(实体框架)的失望(另请参阅此Uservoice),我编写了一些 Linqpad 代码来重新排序内容。然而,在 LinqPad 之外使用它很容易(而且很明显)。
It orders the elements by element-type (tag), then by the value of the element-attribute "Name", and then by some other stuff to try to make it sort of deterministic (different xml, but same meaning, is [usually] same output - see code).
它按元素类型(标签)对元素进行排序,然后是元素属性“名称”的值,然后是其他一些东西以尝试使其具有确定性(不同的 xml,但相同的含义,[通常是] 相同的输出 - 见代码)。
It also orders the attributes. Note that semanticallyXML-attributes may have no (relevant) order, but textuallythey do, and version control systems still consider them plain text...
它还对属性进行排序。请注意,语义上的XML 属性可能没有(相关)顺序,但在文本上它们确实如此,并且版本控制系统仍将它们视为纯文本......
(Note that it does not fix the different aliases, mentioned in Entity Framework edmx file regenerating differently amongst team)
(请注意,它不修复不同的别名,在Entity Framework edmx 文件中提到的不同的别名在团队中以不同的方式重新生成)
void Main()
{
XDocument xdoc = XDocument.Load(@"\filepath1\file1.edmx");
var orderedElements = CopyAndSortElements(xdoc.Elements());
var newDoc = new XDocument();
newDoc.Add(orderedElements);
newDoc.Save(@"\filepath1\file1.Ordered.edmx");
}
public IEnumerable<XElement> CopyAndSortElements(IEnumerable<XElement> elements)
{
var newElements = new List<XElement>();
// Sort XElements by Tag & name-attribute (and some other properties)
var orderedElements = elements.OrderBy(elem => elem.Name.LocalName) // element-tag
.ThenByDescending(elem => elem.Attributes("Name").Count()) // can be 0, more than 1 is invalid XML
.ThenBy(elem => (elem.Attributes("Name").Any() ? elem.Attributes("Name").First().Value.ToString() : string.Empty))
// in case of no Name-Attributes, try to sort by (number of) children
.ThenBy(elem => elem.Elements().Count())
.ThenBy(elem => elem.Attributes().Count())
// next line may vary for textually different but semantically equal input when elem & attr were unordered on input, but I need to restrain myself...
.ThenBy(elem => elem.ToString());
foreach (var oldElement in orderedElements)
{
var newElement = new XElement(oldElement.Name);
if (oldElement.HasElements == false && string.IsNullOrEmpty(oldElement.Value) == false)
{
// (EDMX does not have textual nodes, but SO-users may use it for other XML-types ;-) )
// IsNullOrEmpty-check: not setting empty value keeps empty-element tag, setting value (even empty) causes start-tag immediately followed by an end-tag
// (empty-element tags may be a matter of taste, but for textual comparison it will matter!)
newElement.Value = oldElement.Value;
}
var orderedAttrs = oldElement.Attributes().OrderBy(attr => attr.Name.LocalName).ThenBy(attr => attr.Value.ToString());
newElement.Add(orderedAttrs);
newElement.Add(CopyAndSortElements(oldElement.Elements()));
newElements.Add(newElement);
}
return newElements;
}
PS: We ended up using an XSLT, which somebody else wrote at the same time. I think it fitted easier/better in everybody's build process. But maybe/hopefully this is of some use to somebody.
PS:我们最终使用了其他人同时编写的 XSLT。我认为它在每个人的构建过程中都更容易/更好。但也许/希望这对某人有用。
回答by Steven T. Cramer
I came accross this post when trying to figure out how to sort and edmx file. My solution was based on the Arvo Bowens solution found https://stackoverflow.com/a/19324438/212241
当我试图弄清楚如何对 edmx 文件进行排序和排序时,我遇到了这篇文章。我的解决方案基于找到的 Arvo Bowens 解决方案 https://stackoverflow.com/a/19324438/212241
void Main()
{
XDocument xdoc = XDocument.Load(@"C:\git\Nvision\Source\NvisionEntities\NvisionModel.edmx");
Sort(xdoc.Root);
xdoc.Save(@"C:\git\Nvision\Source\NvisionEntities\NvisionModel.edmx");
}
public void Sort(XElement source, bool bSortAttributes = true)
{
//Make sure there is a valid source
if (source == null) throw new ArgumentNullException("source");
//Sort attributes if needed
if (bSortAttributes)
{
List<XAttribute> sortedAttributes = source.Attributes().OrderBy(a => a.ToString()).ToList();
sortedAttributes.ForEach(a => a.Remove());
sortedAttributes.ForEach(a => source.Add(a));
}
//Sort the children IF any exist
List<XElement> sortedChildren = source.Elements().OrderBy(elem => elem.Attributes("Name").Any() ? elem.Attributes("Name").First().Value.ToString() : string.Empty).ToList();
if (source.HasElements)
{
source.RemoveNodes();
sortedChildren.ForEach(c => Sort(c));
sortedChildren.ForEach(c => source.Add(c));
}
}

