好的,基于这个问题,XSLT 1.0 sort elements,我不明白为什么以下内容不起作用:
我有以下XML:
<?xml version="1.0" encoding="UTF-8"?>
<viewentries>
<viewentry>
<entrydata name="Waste">
<text>Bric-a-Brac</text>
</entrydata>
<entrydata name="Disposal">
<text/>
</entrydata>
</viewentry>
<viewentry>
<entrydata name="Waste">
<textlist>
<text>Paper</text>
<text>Glass</text>
</textlist>
</entrydata>
<entrydata name="Disposal">
<text/>
</entrydata>
</viewentry>
<viewentry>
<entrydata name="Waste">
<textlist>
<text>Paper</text>
<text>Cans</text>
</textlist>
</entrydata>
<entrydata name="Disposal">
<text>Washing Machines</text>
<text>Cars</text>
</entrydata>
</viewentry>
</viewentries>以及以下XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="k1" match="entrydata[@name = 'Waste' or @name = 'Disposal']//text" use="concat(ancestor::entrydata/@name, '|', .)"/>
<xsl:template match="viewentries">
<categories>
<xsl:apply-templates/>
</categories>
</xsl:template>
<xsl:template match="viewentry">
<xsl:apply-templates select="entrydata[@name = 'Waste' or @name = 'Disposal']//text
[generate-id() = generate-id(key('k1', concat(ancestor::entrydata/@name, '|', .))[1])]">
<xsl:sort select="."/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="text[normalize-space() != '']">
<category type="{ancestor::entrydata/@name}">
<xsl:apply-templates/>
</category>
</xsl:template>
</xsl:stylesheet>这提供了以下输出:
<?xml version="1.0" encoding="UTF-8"?>
<categories>
<category type="Waste">Bric-a-Brac</category>
<category type="Waste">Glass</category>
<category type="Waste">Paper</category>
<category type="Waste">Cans</category>
<category type="Disposal">Cars</category>
<category type="Disposal">Washing Machines</category>
</categories>我需要按顺序排序的输出:
<?xml version="1.0" encoding="UTF-8"?>
<categories>
<category type="Waste">Bric-a-Brac</category>
<category type="Waste">Cans</category>
<category type="Disposal">Cars</category>
<category type="Waste">Glass</category>
<category type="Waste">Paper</category>
<category type="Disposal">Washing Machines</category>
</categories>我做错什么了?
编辑:
它似乎只基于<entrydata>的第一个<entrydata>值而不是所有<text>值进行排序。
然而,这个样式表工作得很好:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="k1" match="entrydata[@name = 'Waste' or @name = 'Disposal']//text" use="concat(ancestor::entrydata/@name, '|', .)"/>
<xsl:template match="viewentries">
<categories>
<xsl:apply-templates select="viewentry/entrydata[@name = 'Waste' or @name = 'Disposal']//text
[generate-id() = generate-id(key('k1', concat(ancestor::entrydata/@name, '|', .))[1])]">
<xsl:sort select="."/>
</xsl:apply-templates>
</categories>
</xsl:template>
<xsl:template match="text[normalize-space() != '']">
<category type="{ancestor::entrydata/@name}">
<xsl:value-of select="."/>
</category>
</xsl:template>
</xsl:stylesheet>有人能解释为什么第一个例子不起作用,而第二个例子却起作用。
发布于 2012-07-18 01:22:19
有人能解释为什么将排序应用于第一个模板是有效的,但是当应用于第二个模板时,就像我在最初的问题中那样,它不会?
这是您的“第二个模板”:
<xsl:template match="text[normalize-space() != '']">
<category type="{ancestor::entrydata/@name}">
<xsl:apply-templates>
<xsl:sort select="."/>
</xsl:apply-templates>
</category>
</xsl:template>在这里,您希望根据当前节点的字符串值对其子节点进行排序。
但是,在提供的XML文档中,任何text元素都有一个文本--节点子--因此没有任何可以排序的东西!
在这个问题和上一个问题中,你犯了同样的错误--试图排序必须排序的元素的子元素--你排序太晚了。
记住
<xsl:apply-templates/>是的缩写
<xsl:apply-templates select="child::node()"/>因此,这意味着:将模板应用于我的孩子“--而不是”将模板应用到我身上“。
Update:下面是一个正确的解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kCatVal" match="text[text()]" use="concat(../@name, '+', .)"/>
<xsl:template match="/">
<categories>
<xsl:apply-templates select=
"//text[generate-id()
=
generate-id(key('kCatVal',
concat(../@name, '+', .)
)[1]
)
]">
<xsl:sort/>
</xsl:apply-templates>
</categories>
</xsl:template>
<xsl:template match="text">
<category type="{../@name}"><xsl:value-of select="."/></category>
</xsl:template>
</xsl:stylesheet>在提供的XML文档上应用时
<viewentries>
<viewentry>
<entrydata name="Waste">
<text>Bric-a-Brac</text>
</entrydata>
<entrydata name="Disposal">
<text/>
</entrydata>
</viewentry>
<viewentry>
<entrydata name="Waste">
<textlist>
<text>Paper</text>
<text>Glass</text>
</textlist>
</entrydata>
<entrydata name="Disposal">
<text/>
</entrydata>
</viewentry>
<viewentry>
<entrydata name="Waste">
<textlist>
<text>Paper</text>
<text>Cans</text>
</textlist>
</entrydata>
<entrydata name="Disposal">
<text>Washing Machines</text>
<text>Cars</text>
</entrydata>
</viewentry>
</viewentries>想要的,正确的结果产生
<categories>
<category type="Waste">Bric-a-Brac</category>
<category type="">Cans</category>
<category type="Disposal">Cars</category>
<category type="">Glass</category>
<category type="">Paper</category>
<category type="Disposal">Washing Machines</category>
</categories>Explanation:
这种分组要求基于包含两个部分的复合键进行索引。因此,use属性xsl:key被指定为这两个部分的连接,由我们知道它们的值中不存在的一个字符连接在一起(以避免当第一个键组件的值是第二个键组件的值的前缀时出现假阳性)。
https://stackoverflow.com/questions/11523678
复制相似问题