web-dev-qa-db-ja.com

XMLソート/フォーマットツール

XMLファイルを(プリティプリント)フォーマットし、その要素と属性の両方をソートできるツールはありますか?

15

私はこの投稿を見つけました: 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>

まだ試していませんが、フォーマットを行うためにXSLTに固執する可能性があります。

3

私はこのツールが好きでした: https://xmlsorter.codeplex.com/

タグ名と属性で並べ替えることができます。いくつかのXMLファイルを比較する前にそれを使用するのが好きです。

XML Sorter main window

14
Akira Yamamoto

同様のユーティリティを探していましたが、探しているものが実際には見つからなかったため、代わりにほとんど作成しませんでした。これは非常に単純です(ノードの並べ替えに属性が含まれていません)が、機能します。

多分それは他の人に役立つでしょう..それは GitHub にあります。

これが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.)

デフォルトでは、きれいでソートされたノードと属性が出力されます。次に例を示します。

> 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>
8
wasatchwizard

常にEDMXファイル(Entity Framework)を並べ替えて書き直しているように見えるVisual Studioへの不満から(これも参照 servoice )、並べ替え用のLinqpadコードをいくつか作成しました。ただし、LinqPadの外部で使用するのは簡単です(そして明白です)。

要素を要素タイプ(タグ)、要素属性「名前」の値、その他の要素の順に並べて、決定論的なものにしようとします(xmlは異なりますが、同じ意味ですが、通常は[ ]同じ出力-コードを参照)。

また、属性を並べ替えます。 semanticallyXML属性には(関連する)順序がない場合がありますが、textuallyそうです、そしてバージョン管理システムはまだそれらをプレーンテキストと見なします...

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:他の誰かが同時に書いたXSLTを使用することになりました。みんなのビルドプロセスに、より簡単に、より良く適合したと思います。しかし、多分/うまくいけば、これは誰かに役立つでしょう。

4
Yahoo Serious

ファイルの並べ替えと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));
    }
}
0