我正在尝试按字母顺序对字段进行排序(在本例中为 VICINITY),但如果不存在 (VICINITY),我需要考虑另一个字段 (ITA_LIGHT_NAME),从而创建两个嵌套排序。
我创建这个 xslt:
<xsl:text>List A<xsl:text>
<xsl:for-each select="//VICINITY[not(. = preceding::VICINITY)]">
<xsl:sort select="." data-type="text" order="ascending"/>
<xsl:sort select="preceding-sibling::ITA_LIGHT_NUMBER" data-type="text" order="ascending"/>
<xsl:variable name ="localita" select="."/>
<xsl:value-of select="."/>
<br/>
</xsl:for-each>
<br/>
<xsl:text>List B<xsl:text>
<xsl:for-each select="//ITA_LIGHT_NAME[not(. = preceding::ITA_LIGHT_NAME)]">
<xsl:if test="not(preceding-sibling::VICINITY)">
<xsl:value-of select="."/><br/>
</xsl:if>
</xsl:for-each>
这给出了两个结果(列表 A 和列表 B 分为两个不同的列表):
List A
ANCONA (Only one time)
GENOVA
MESSINA
VENEZIA
List B
Capo Peloro
Capo Rizzuto (Only one time)
但是,我真的很想最终输出一个列表(按字母顺序排序):
ANCONA (Only one time)
Capo Peloro
Capo Rizzuto (Only one time)
GENOVA
MESSINA
VENEZIA
实际上,应按以下方式工作:如果存在,则按 VICINITY 的字母顺序排序(无重复),如果不存在,则按ITA_LIGHT_NAME(无重复)排序。
这是我的XML,你能帮忙模拟这个输出吗:
<SECTION_CONTENT_LIST>
<SECTION_CONTENT_LIST_ITEM>
<NTC_LIGHTLISTPRODUCT>
<ITA_LIGHT_NUMBER>3921.9</ITA_LIGHT_NUMBER>
<VICINITY>ANCONA</VICINITY>
<ITA_LIGHT_NAME>Installazioni 1</ITA_LIGHT_NAME>
</NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
<NTC_LIGHTLISTPRODUCT>
<ITA_LIGHT_NUMBER>3924</ITA_LIGHT_NUMBER>
<VICINITY>ANCONA</VICINITY>
<ITA_LIGHT_NAME>Installazioni 2</ITA_LIGHT_NAME>
</NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
<NTC_LIGHTLISTPRODUCT>
<ITA_LIGHT_NUMBER>1577</ITA_LIGHT_NUMBER>
<VICINITY>GENOVA</VICINITY>
<ITA_LIGHT_NAME>Granarolo</ITA_LIGHT_NAME>
</NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
<NTC_LIGHTLISTPRODUCT>
<ITA_LIGHT_NUMBER>2746</ITA_LIGHT_NUMBER>
<VICINITY>MESSINA</VICINITY>
<ITA_LIGHT_NAME>Meda elastica</ITA_LIGHT_NAME>
</NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
<NTC_LIGHTLISTPRODUCT>
<ITA_LIGHT_NUMBER>4231.4</ITA_LIGHT_NUMBER>
<VICINITY>VENEZIA</VICINITY>
<ITA_LIGHT_NAME>Segnale da nebbia</ITA_LIGHT_NAME>
</NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
<NTC_LIGHTLISTPRODUCT>
<ITA_LIGHT_NUMBER>2736</ITA_LIGHT_NUMBER>
<ITA_LIGHT_NAME>Capo Peloro</ITA_LIGHT_NAME>
</NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
<NTC_LIGHTLISTPRODUCT>
<ITA_LIGHT_NUMBER>3396</ITA_LIGHT_NUMBER>
<ITA_LIGHT_NAME>Capo Rizzuto</ITA_LIGHT_NAME>
</NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
<NTC_LIGHTLISTPRODUCT>
<ITA_LIGHT_NUMBER>3399</ITA_LIGHT_NUMBER>
<ITA_LIGHT_NAME>Capo Rizzuto</ITA_LIGHT_NAME>
</NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
</SECTION_CONTENT_LIST>
实际上,应按以下方式工作:按字母顺序排序 VICINITY(无重复) 如果存在,如果不存在,则按顺序排序 ITA_LIGHT_NAME(不重复)。
不,它不能那样工作。您首先需要做的是仅获取不同的记录(如果存在,请考虑VICINITY,否则ITA_LIGHT_NAME),然后按相同方式对结果进行排序。
第一步是通过一种称为Muenchian分组的方法完成的 - 在这里阅读:http://www.jenitennison.com/xslt/grouping/muenchian.html
另请注意,您的输入缺少根元素。添加后,您可以尝试:
XSLT 1.0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:key name="k" match="NTC_LIGHTLISTPRODUCT" use="VICINITY | ITA_LIGHT_NAME[not(../VICINITY)]" />
<xsl:template match="/">
<xsl:for-each select="root/NTC_LIGHTLISTPRODUCT[count(. | key('k', VICINITY | ITA_LIGHT_NAME[not(../VICINITY)])[1]) = 1]">
<xsl:sort select="VICINITY | ITA_LIGHT_NAME[not(../VICINITY)]"/>
<xsl:value-of select="VICINITY | ITA_LIGHT_NAME[not(../VICINITY)]"/>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
获得:
ANCONA
Capo Peloro
Capo Rizzuto
GENOVA
MESSINA
VENEZIA
我从michael.hor257k的解决方案开始(将我引导到正确的解决方案),我正在使用 http://xslttest.appspot.com/
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:key name="k" match="ITA_LIGHT_NUMBER" use="following-sibling::VICINITY | following-sibling::ITA_LIGHT_NAME[not(../preceding-sibling::VICINITY)]" />
<xsl:template match="/">
<xsl:for-each select="//ITA_LIGHT_NUMBER[count(. | key('k', following-sibling::VICINITY | following-sibling::ITA_LIGHT_NAME[not(../VICINITY)])[1]) = 1]">
<xsl:sort select="following-sibling::VICINITY | following-sibling::ITA_LIGHT_NAME[not(../preceding-sibling::VICINITY)]"/>
<xsl:value-of select="following-sibling::VICINITY | following-sibling::ITA_LIGHT_NAME[not(../preceding-sibling::VICINITY)]"/>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
<br/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
感谢Michael.hor257k您的合作非常宝贵。