我有以下想要排序的xml结构
<ESTABLISHMENTS>
<ESTABLISHMENT>
<NAME>A</NAME>
<LOCATION>
<LOCALITY>A</LOCALITY>
</LOCATION>
<RATING>
<LEVEL>1</LEVEL>
<SCORE>50</SCORE>
</RATING>
</ESTABLISHMENT>
<ESTABLISHMENT>
<NAME>C</NAME>
<LOCATION>
<LOCALITY>B</LOCALITY>
</LOCATION>
<RATING>
<LEVEL>2</LEVEL>
<SCORE>50</SCORE>
</RATING>
</ESTABLISHMENT>
<ESTABLISHMENT>
<NAME>B</NAME>
<LOCATION>
<LOCALITY>B</LOCALITY>
</LOCATION>
<RATING>
<LEVEL>2</LEVEL>
<SCORE>50</SCORE>
</RATING>
</ESTABLISHMENT>
</ESTABLISHMENTS>
我的目标是先按地点排序,然后按评级,然后按评分,最后按名称排序。 我已设法使用以下代码
进行排序<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" omit-xml-declaration="no"/>
<xsl:key name="establishment-by-locality" match="ESTABLISHMENTS/ESTABLISHMENT/LOCATION"
use="LOCALITY"/>
<xsl:template match="EXPORT">
<xsl:for-each select="ESTABLISHMENTS/ESTABLISHMENT/LOCATION[count(.| key('establishment-by-locality', LOCALITY)[1]) = 1]">
<xsl:sort select="LOCALITY"/>
<xsl:for-each select="key('establishment-by-locality', LOCALITY)">
<xsl:sort select="../RATING/LEVEL" data-type="number" order="descending"/>
<xsl:sort select="../RATING/MERIT_SCORE" data-type="number" order="descending"/>
<xsl:sort select="../NAME"/>
<xsl:apply-templates select="ancestor::ESTABLISHMENT" mode="test"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template match="node()" mode="test">
<hotel>
<name>
<xsl:value-of select="NAME"/>
</name>
<town>
<xsl:value-of select="LOCATION/LOCALITY"/>
</town>
<level>
<xsl:value-of select="RATING/LEVEL"/>
</level>
<score>
<xsl:value-of select="RATING/MERIT_SCORE"/>
</score>
</hotel>
</xsl:template></xsl:stylesheet>
但是,一旦对XML进行了排序,我想将“LOCALITY”值与新的进程建立进行比较,但仍受到仍使用原始树的XPath的限制。不幸的是,我被限制在XSLT 1.0,因为目的地是Adobe InDesign。
非常感谢任何帮助。
修改
比较的目的是决定是否插入和附加元素,即如果地点不同则添加节标题。
最终所需的输出是以下几行
<establishments>
<town>
<townName>A</townName>
<hotel>
<name>A</name>
<town>A</town>
<level>1</level>
<score>50</score>
</hotel>
</town>
<town>
<townName>B</townName>
<hotel>
<name>B</name>
<town>B</town>
<level>2</level>
<score>50</score>
</hotel>
<hotel>
<name>C</name>
<town>B</town>
<level>2</level>
<score>50</score>
</hotel>
</town>
</establishments>
答案 0 :(得分:1)
我看到没有必要进行这样的比较。通过将以下样式表应用于示例输入,可以轻松获得预期输出:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="establishment-by-locality" match="ESTABLISHMENT" use="LOCATION/LOCALITY"/>
<xsl:template match="/ESTABLISHMENTS">
<establishments>
<xsl:for-each select="ESTABLISHMENT[count(.| key('establishment-by-locality', LOCATION/LOCALITY)[1]) = 1]">
<xsl:sort select="LOCATION/LOCALITY"/>
<town>
<townName>
<xsl:value-of select="LOCATION/LOCALITY"/>
</townName>
<xsl:apply-templates select="key('establishment-by-locality', LOCATION/LOCALITY)">
<xsl:sort select="RATING/LEVEL" data-type="number" order="descending"/>
<xsl:sort select="RATING/SCORE" data-type="number" order="descending"/>
<xsl:sort select="NAME"/>
</xsl:apply-templates>
</town>
</xsl:for-each>
</establishments>
</xsl:template>
<xsl:template match="ESTABLISHMENT">
<hotel>
<name>
<xsl:value-of select="NAME"/>
</name>
<town>
<xsl:value-of select="LOCATION/LOCALITY"/>
</town>
<level>
<xsl:value-of select="RATING/LEVEL"/>
</level>
<score>
<xsl:value-of select="RATING/SCORE"/>
</score>
</hotel>
</xsl:template>
</xsl:stylesheet>
注意:显然您的实际输入结构略有不同。你必须自己做出调整。