说我有以下xml:
<?xml version="1.0" encoding="UTF-8"?>
<Test xmlns="http://someorg.org">
<name>
<use value="usual"/>
<family value="family"/>
<given value="given"/>
<suffix value="MSc"/>
</name>
</Test>
我希望改变顺序,例如在家庭之前给出,以便我们有:
<?xml version="1.0" encoding="UTF-8"?>
<Test xmlns="http://someorg.org">
<name>
<use value="usual"/>
<given value="given"/>
<family value="family"/>
<suffix value="MSc"/>
</name>
</Test>
我尝试使用xsl:paply.template,但问题是,由于apply-templates将模板应用于所有子节点,它还会输出其命令再次被更改的节点,我不知道如何阻止它从将模板应用到订单已被更改的节点。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://someorg.org"
xmlns="http://someorg.org"
exclude-result-prefixes="f xsl">
<xsl:template match="*">
<xsl:element name="{local-name(.)}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match = "f:name">
<xsl:apply-templates select = "f:given"/>
<xsl:apply-templates select = "f:family"/>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:3)
要更改您需要的顺序apply-templates
,即
<xsl:template match = "f:name">
<xsl:copy>
<xsl:apply-templates select="f:use"/>
<xsl:apply-templates select="f:given"/>
<xsl:apply-templates select="f:family"/>
<xsl:apply-templates select="f:suffix"/>
</xsl:copy>
</xsl:template>
使用XSLT 2.0更容易编写
<xsl:template match = "f:name">
<xsl:copy>
<xsl:apply-templates select="f:use, f:given, f:family, f:suffix"/>
</xsl:copy>
</xsl:template>
答案 1 :(得分:2)
这是一个通用而简短的完整XSLT 1.0解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://someorg.org">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vOrdered" select="'|use|given|family|suffix|'"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="my:name">
<xsl:copy>
<xsl:apply-templates select="*">
<xsl:sort select="substring-before($vOrdered, concat('|',name(),'|'))"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<Test xmlns="http://someorg.org">
<name>
<use value="usual"/>
<family value="family"/>
<given value="given"/>
<suffix value="MSc"/>
</name>
</Test>
生成了想要的正确结果:
<Test xmlns="http://someorg.org">
<name>
<use value="usual"/>
<given value="given"/>
<family value="family"/>
<suffix value="MSc"/>
</name>
</Test>
请注意:
如果我们想要指定<xsl:apply-templates>
元素子元素的新顺序,则只使用一条f:name
指令并且不会更改模板的代码。
元素的排序可以在一个单独的XML文档中指定,该文档可以使用标准函数动态获取,例如document()
到当前的XSLT样式表中并用作独立的&#34;配置文件&#34 ;.然后,当需要新的排序时,永远不需要修改转换 - 只需要修改配置文件。