用于Linux的开源命令行工具,用于区分忽略元素顺序的XML文件

use*_*270 10 xml sorting diff command-line open-source

是否有一个开源命令行工具(用于Linux)来区分忽略元素顺序的XML文件?

示例输入文件a.xml:

<tag name="AAA">
  <attr name="b" value="1"/>
  <attr name="c" value="2"/>
  <attr name="a" value="3"/>
</tag>

<tag name="BBB">
  <attr name="x" value="111"/>
  <attr name="z" value="222"/>
</tag>
<tag name="BBB">
  <attr name="x" value="333"/>
  <attr name="z" value="444"/>
</tag>
Run Code Online (Sandbox Code Playgroud)

b.xml:

<tag name="AAA">
  <attr name="a" value="3"/>
  <attr name="b" value="1"/>
  <attr name="c" value="2"/>
</tag>

<tag name="BBB">
  <attr name="z" value="444"/>
  <attr name="x" value="333"/>
</tag>
<tag name="BBB">
  <attr name="x" value="111"/>
  <attr name="z" value="222"/>
</tag>
Run Code Online (Sandbox Code Playgroud)

因此,比较这两个文件不应该输出任何差异.我试图先用XSLT对文件进行排序:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="WINDOWS-1252" omit-xml-declaration="no" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*">
        <xsl:sort select="@*" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

但问题是,元素<tag name="BBB">没有排序.它们只是输出它们输入的顺序.

我已经看了diffXml,xDiff,XMLUnit,xmlstarlet但这些都不解决问题; diff输出应该是人类可读的,例如在使用时diff.

关于如何解决排序或忽略元素顺序差异的任何提示?谢谢!

C. *_*een 0

您请求根据要排序的元素中的属性顺序进行排序。但这里的顶级tag元素只有一个属性:name。如果您希望多个tag元素以name="BBB"不同的方式排序,则需要为它们提供不同的排序键。

在你的例子中,我会尝试类似的东西select="concat(name(), @name, name(*[1]), *[1]/@name)"——但这是一个非常浅的密钥。它使用输入中第一个子级的值,但子级可能会在此过程中移动位置。您也许能够(比我更了解您的数据)在一次传递中为每个元素计算一个好的密钥,或者您可能只需要几次传递。