XSLT命令属性

时间:2013-10-31 23:50:09

标签: 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>

我需要应用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>

唯一的变化是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>

mytest.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <attributes>
        <attribute>b:type</attribute>
        <attribute>id</attribute>
    </attributes>

2 个答案:

答案 0 :(得分:7)

根据{{​​3}}:

Attribute order is insignificant

  

请注意start-tag或中的属性规范的顺序   空元素标签不重要。

因此,XSLT无法控制输出中的属性排序。

W3C建议书中的属性排序

通常,XML建议都会认为属性排序无关紧要,但如果您的应用程序需要属性排序,请参阅XML Recommendation中的section on attribute processingXML Normalization Recommendation。但是,您必须在标准XSLT之外执行此操作。

属性排序实施黑客

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

正如Michael Kay在另一个问题的答案中提到的那样,Saxon 9.5(PE或更高版本)具有XSLT扩展,可以控制序列化程序的属性排序。有关详细信息,请参阅Canonical XML Recommendation

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

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

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

将XML属性视为具有排序与XMLStreamWriter.writeAttribute相反,应该避免使用。

答案 1 :(得分:3)

Saxon 9.5(PE或更高版本)提供序列化选项saxon:attribute-order,允许您控制序列化程序生成的属性顺序。虽然属性顺序不应该对任何理智的接收应用程序产生任何影响,但是一致的排序可以提高XML的人类可读性,并且由于人类可读性是XML的目标之一,我认为这是一个合理的添加功能。