Обработка списка в XSLT

#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),'|'))]">