我找到了一些类似的问题,但是却努力将解决方案“弯曲”到我需要的地方,所以再次向你道歉。
我有一些像这样的XML ....
<?xml version="1.0" encoding="UTF-8"?>
<ns:Root
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns="urn:Test.Namespace"
xsi:schemaLocation="urn:Test.Namespace Test1.xsd"
>
<ns:element1 id="001">
<ns:element2 id="001.1" order="1">
<ns:element3 id="001.1.1" />
</ns:element2>
<ns:element2 id="001.2" order="2">
<ns:element3 id="001.1.2" />
</ns:element2>
</ns:element1>
<ns:element1 id="003">
<ns:element2 id="007.0" order="1">
<ns:element3 id="007.1.1" />
</ns:element2>
</ns:element1>
<ns:element1 id="002">
<ns:element2 id="002.1" order="3">
<ns:element3 id="002.1.1" />
</ns:element2>
<ns:element2 id="002.2" order="4">
<ns:element3 id="002.1.2" />
</ns:element2>
</ns:element1>
</ns:Root>
我写过这个XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="urn:Test.Namespace"
>
<xsl:output indent="no" />
<xsl:template match="text()[not(string-length(normalize-space()))]"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates>
<xsl:sort select="/ns:Root/ns:element1/@id" />
<xsl:copy-of select="." />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="ns:element1">
<xsl:copy-of select="." />
<xsl:apply-templates />
</xsl:template>
<xsl:template match="ns:element2">
<xsl:copy-of select="." />
<xsl:apply-templates />
</xsl:template>
<xsl:template match="ns:element3">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
(我从这里how to sort xml? <)获得了大纲。
我希望能够使用此XSLT通过element1的id属性对原始XML进行排序并生成XML。这个想法是,一旦它被排序,那么我可以与其他一些XSLT一起处理以获得最终结果。
不幸的是,这并没有给我任何输出,这让我觉得有一个非常愚蠢的错字。在某个地方,但我看不到它。
任何帮助都将不胜感激。
由于
答案 0 :(得分:3)
您的问题都在于此匹配模板
<xsl:template match="/">
<xsl:apply-templates>
<xsl:sort select="/ns:Root/ns:element1/@id" />
<xsl:copy-of select="." />
</xsl:apply-templates>
</xsl:template>
首先,\
符号与文档级元素匹配,后者与根 ns:Root 不同,但与此有一个级别。这意味着当你执行<xsl:apply-templates>
时,所有选择的是 ns:root 元素,其中只有一个,所以没有必要对它进行排序!
你可能需要开始的是匹配根元素,复制它然后开始对孩子进行排序。
<xsl:template match="/*">
<xsl:copy>
<!-- Code to select and sort childrens -->
</xsl:copy>
</xsl:template>
您遇到的下一个问题是使用sort语句。您正在使用xpath表达式/ns:Root/ns:element1/@id
,但这是一个绝对路径,而不是相对路径,因此只会获取文档中第一个 ns:element1 的@id属性
假设您已经定位在根元素上,并且假设它只有 ns:element1 元素作为子元素,那么您可以这样做
<xsl:apply-templates>
<xsl:sort select="@id" />
</xsl:apply-templates>
您遇到的最后一个问题是您的 xsl:apply-templates 中有<xsl:copy-of select="." />
声明,这是不允许的。你可能应该在这里使用 xsl:copy ,如上所示。
值得指出的是,如果您还没有意识到,最好使用XSLT identity transform复制现有元素,除非您想以某种方式更改它们。这样您就不必为每种特定类型的元素创建模板。
尝试以下XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="urn:TestNamespace" >
<xsl:output indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="text()[not(string-length(normalize-space()))]"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates>
<xsl:sort select="@id" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用于XML时,输出以下内容
<ns:Root xmlns:ns="urn:Test.Namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:Test.Namespace Test1.xsd">
<ns:element1 id="001">
<ns:element2 id="001.1" order="1">
<ns:element3 id="001.1.1"/>
</ns:element2>
<ns:element2 id="001.2" order="2">
<ns:element3 id="001.1.2"/>
</ns:element2>
</ns:element1>
<ns:element1 id="002">
<ns:element2 id="002.1" order="3">
<ns:element3 id="002.1.1"/>
</ns:element2>
<ns:element2 id="002.2" order="4">
<ns:element3 id="002.1.2"/>
</ns:element2>
</ns:element1>
<ns:element1 id="003">
<ns:element2 id="007.0" order="1">
<ns:element3 id="007.1.1"/>
</ns:element2>
</ns:element1>
</ns:Root>
答案 1 :(得分:0)
是的,这是一个简单的拼写错误。 只需将XSLT中的命名空间更改为您在XML中使用的命名空间即可。 - 反之亦然。
xmlns:ns="urn:Test.Namespace" -> xmlns:ns="urn:TestNamespace"
第二个修复(基于您的评论)只包括交换。
<xsl:template match="/">
<xsl:apply-templates>
<xsl:sort select="/ns:Root/ns:element1/@id" />
<xsl:copy-of select="." />
</xsl:apply-templates>
</xsl:template>
到
<xsl:template match="/">
<xsl:apply-templates select="ns:Root/ns:element1">
<xsl:sort select="@id" />
</xsl:apply-templates>
</xsl:template>