Reputation: 473
I'm trying to sort alphabetically fields (in this case VICINITY), but if not exist (VICINITY), I need to consider another field (ITA_LIGHT_NAME), thereby creating two nested sort.
I create this 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>
This give two result (List A and List B divided in two different list):
List A
ANCONA (Only one time)
GENOVA
MESSINA
VENEZIA
List B
Capo Peloro
Capo Rizzuto (Only one time)
But, I really would like as final output a single list(sorted alphabetically):
ANCONA (Only one time)
Capo Peloro
Capo Rizzuto (Only one time)
GENOVA
MESSINA
VENEZIA
Practically, should work in the following way: Order alphabetically by VICINITY(without repetition) if exist, if not exist, order by ITA_LIGHT_NAME(without repetition).
Thi is my XML, can you Help to simulate this output:
<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>
Upvotes: 0
Views: 449
Reputation: 473
I am starting from the solution of michael.hor257k (directed me to a correct solution), I am try it using 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>
Thanks Michael.hor257k your collaboration has been invaluable.
Upvotes: 1
Reputation: 116992
Practically, should work in the following way: Order alphabetically by VICINITY(without repetition) if exist, if not exist, order by ITA_LIGHT_NAME(without repetition).
No, it cannot work that way. What you need to do first is get only distinct records (considering VICINITY if it exists, ITA_LIGHT_NAME otherwise), then sort the results by the same.
The first step is done through a method known as Muenchian grouping - read about it here: http://www.jenitennison.com/xslt/grouping/muenchian.html
Note also that your input is missing a root element. Once you add it, you can try:
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>
to obtain:
ANCONA
Capo Peloro
Capo Rizzuto
GENOVA
MESSINA
VENEZIA
Upvotes: 1