XSLT命令属性

use*_*360 3 xml xslt

如何使用XSLT控制属性排序?

我有一个输入XML文档:

输入XML

<?xml version="1.0" encoding="UTF-8"?>
<allNames id="ID_0" b:type="a:UnstructuredName">
    <typeName>KnownBy</typeName>
    <startDate>2001-01-01-05:00</startDate>
    <fullName>ABCD 004 COMPANY INC</fullName>
</allNames>
Run Code Online (Sandbox Code Playgroud)

我需要应用XSLT将其转换为

输出XML

<?xml version="1.0" encoding="UTF-8"?>
<allNames  b:type="a:UnstructuredName"  id="ID_0">
    <typeName>KnownBy</typeName>
    <startDate>2001-01-01-05:00</startDate>
    <fullName>ABCD 004 COMPANY INC</fullName>
</allNames>
Run Code Online (Sandbox Code Playgroud)

唯一的变化是元素中的属性排序更改allNames.我查了另一篇文章并编写了命令属性的XSLT,但我不知道如何让整个工作正常.

XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" indent="yes"/>
    <xsl:variable name="attributes" select="document('mytest.xml')//attribute"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*">
        <xsl:variable name="self" select="."/>
        <xsl:for-each select="$attributes">
            <xsl:apply-templates select="$self/@*[name()=current()]"/>
        </xsl:for-each>   
     </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

mytest.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <attributes>
        <attribute>b:type</attribute>
        <attribute>id</attribute>
    </attributes>
Run Code Online (Sandbox Code Playgroud)

kjh*_*hes 7

根据 XML建议书,属性顺序无关紧要:

请注意,start-tag或empty-element标记中的属性规范的顺序并不重要.

因此,XSLT无法控制输出上的属性排序.

W3C建议书中的属性排序

通常,XML建议都会认为属性排序无关紧要,但如果您的应用程序需要属性排序,请参阅XML规范化建议Canonical XML Recommendation中的属性处理部分.但是,您必须在标准XSLT之外执行此操作.

属性排序实现黑客

如果您认识到对XML属性强加排序本质上存在缺陷,则与互操作性相悖,并且完全在XML建议书和使用XML的既定实践之外,但您仍然必须控制属性排序,这里有一些方法实施这种控制......

正如Michael Kay在这个问题的另一个答案中提到的那样,Saxon 9.5(PE或更高版本)具有XSLT扩展,可以控制序列化程序的属性排序.详情saxon:attribute-order请见.

您可以对标准XSLT生成的XML进行后处理.在XML库级别下运行,您当然可以通过字符或字符串级别处理获得对属性排序的完全词法控制.

您可以依赖XML库提供的排序的实现细节.例如,某些库将根据属性的名称按字母顺序写出属性,或者保留提供给它们的属性顺序.显然,依赖于实现细节本质上是不可靠的.也就是说,例如,实施可能XMLStreamWriter.writeAttribute会继续遵守将来赋予它们的属性顺序.

最后重申对XML属性排序的所有问题的真正答案是在关闭之前按顺序...

将XML属性视为具有排序与XML建议书相反,应该避免使用.

  • 就我而言,我想使用一个不支持 XML 的图形比较工具(您知道有一个支持 XML 的工具吗?)。所以我想说有些问题可以通过标准化属性的顺序来解决。 (3认同)