#list #xslt #xslt-1.0
#Список #xslt #xslt-1.0
Вопрос:
У меня есть список элементов в переменной
|ELEMENT1|ELEMENT2|ELEMENT3|ELEMENT4|ELEMENT5|
Если какой-либо из элементов запроса соответствует этому, я должен отобразить локальное имя и его значение.
Запрос XML :
<Root>
<element1>Test1</element1>
<child>
<element2>222</element2>
</child>
<secondChild>
<element2>234</element2>
</secondChild>
<thirdchild>
<element3>5w2</element3>
</thirdchild>
</Root>
XSL:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text"/>
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"></xsl:variable>
<xsl:variable name="list"><xsl:value-of select="'|ELEMENT1|ELEMENT2|ELEMENT3|ELEMENT4|ELEMENT5|'"/></xsl:variable>
<xsl:template match="/">
<xsl:for-each select="//*[contains(translate($list,$lower,$upper),concat('|',translate(local-name(),$lower,$upper),'|'))]">
<xsl:value-of select="concat(local-name(),':',.,'|')"></xsl:value-of>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Ожидаемый результат :
element1:Test1|element2:222|element3:5w2|
Но я получаю
element1:Test1|element2:222|element2:234|element3:5w2|
Это потому, что у меня есть element2 в двух местах в XML. Я не должен читать второй элемент2 во время обработки.
Не могли бы вы помочь в этом
Комментарии:
1. » Если какой-либо из элементов запроса соответствует этому, я должен отобразить локальное имя и его значение». Это именно то, что он делает. «У меня есть element2 в двух местах в XML. Я не должен читать второй элемент2 во время обработки «. Почему бы и нет? В чем здесь логика?
Ответ №1:
Отфильтруйте все элементы, у которых есть предыдущий элемент с тем же именем.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:variable name="list" select="'|ELEMENT1|ELEMENT2|ELEMENT3|ELEMENT4|ELEMENT5|'" />
<xsl:template match="/">
<xsl:for-each select="//*[
contains(
concat('|', translate($list, $lower, $upper), '|'),
concat('|', translate(local-name(), $lower, $upper), '|')
)
]">
<xsl:if test="not(preceding::*[local-name() = local-name(current())])">
<xsl:value-of select="concat(local-name(), ':', ., '|')" />
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Ответ №2:
Вы можете определить ключ
<xsl:key name="name" match="*" use="local-name()"/>
и затем в вашем состоянии вы проверяете
<xsl:for-each select="//*[generate-id() = generate-id(key('name', local-name())[1])][contains(translate($list,$lower,$upper),concat('|',translate(local-name(),$lower,$upper),'|'))]">