Это мой первый вопрос здесь.
Я пытаюсь создать xslt, который преобразует XML в текст.
Мне нужно найти отдельный список конкатенации LANG и OFFICEID , который затем можно использовать в xsl: for-each loop
Я создал минимальную версию XML, с которой я работаю
<docinfo>
<printfile customer="Migrol">
<envelope postagetype="A">
<index name="LANG" value="G"/>
<index name="OFFICEID" value="500"/>
</envelope>
<envelope postagetype="A">
<index name="LANG" value="F"/>
<index name="OFFICEID" value="500"/>
</envelope>
<envelope postagetype="A">
<index name="LANG" value="G"/>
<index name="OFFICEID" value="500"/>
</envelope>
<envelope postagetype="A">
<index name="LANG" value="I"/>
<index name="OFFICEID" value="300"/>
</envelope>
<envelope postagetype="A">
<index name="LANG" value="G"/>
<index name="OFFICEID" value="100"/>
</envelope>
<envelope postagetype="A">
<index name="LANG" value="G"/>
<index name="OFFICEID" value="100"/>
</envelope>
<envelope postagetype="A">
<index name="LANG" value="I"/>
<index name="OFFICEID" value="300"/>
</envelope>
<envelope postagetype="A">
<index name="LANG" value="G"/>
<index name="OFFICEID" value="500"/>
</envelope>
</printfile>
</docinfo>
В XPath 2.0 это можно решить с помощью оператора
/docinfo/printfile/distinct-values(envelope/concat(index[@name='OFFICEID']/@value, index[@name='LANG']/@value))
или
/docinfo/printfile/envelope[not(concat(index[@name='OFFICEID']/@value, index[@name='LANG']/@value)=preceding-sibling::envelope/concat(index[@name='OFFICEID']/@value, index[@name='LANG']/@value))]/concat(index[@name='OFFICEID']/@value, index[@name='LANG']/@value)
К сожалению, я не нашел способа добиться этого в XPath 1.0. Функция concat, кажется, доставляет мне неприятности.
Простая версия XSLT, которую я хочу использовать
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="printfile">
<xsl:for-each select="/docinfo/printfile/envelope[not(concat(index[@name='OFFICEID']/@value, index[@name='LANG']/@value)=preceding-sibling::envelope/concat(index[@name='OFFICEID']/@value, index[@name='LANG']/@value))]">
<xsl:variable name="OID" select="index[@name='OFFICEID'][1]/@value"/>
<xsl:variable name="LANG" select="index[@name='LANG'][1]/@value"/>
<xsl:value-of select="$OID"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$LANG"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
<!-- suppress default text -->
<xsl:template match="text()"/>
</xsl:stylesheet>
Результат должен выглядеть примерно так:
"500 G"
"500 F"
"300 I"
"100 G"
Есть ли у кого-нибудь предложения о том, как этого можно достичь с помощью XSLT и XPath 1.0