XSL уникальные значения на узел

хорошо у меня есть этот xml

<roots>
<root>
    <name>first</name>
    <item type='test'><something>A</something></item>
    <item type='test'><something>B</something></item>
    <item type='test'><something>C</something></item>
    <item type='test'><something>A</something></item>
    <item type='other'><something>A</something></item>
    <item type='test'><something>B</something></item>
    <item type='other'><something>D</something></item>

</root>
<root>
<name>second</name>
    <item type='test'><something>E</something></item>
    <item type='test'><something>B</something></item>
    <item type='test'><something>F</something></item>
    <item type='test'><something>A</something></item>
    <item type='other'><something>A</something></item>
    <item type='test'><something>B</something></item>
    <item type='other'><something>D</something></item>

</root>

</roots>

теперь я должен получить уникальные значения каждого корневого узла до сих пор, я имею

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output indent="yes" method="text"/>
  <xsl:key name="item-by-value" match="something" use="."/>
  <xsl:key name="rootkey" match="root" use="name"/>

  <xsl:template match="/">
    <xsl:for-each select="key('rootkey','second')">
      <xsl:for-each select="item/something">
        <xsl:if test="generate-id() = generate-id(key('item-by-value', normalize-space(.)))">
          <xsl:value-of select="."/>
        </xsl:if>
      </xsl:for-each> 
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

если я использую "Сначала" в качестве ключа для получения только первого корня, я получаю хороший результат ABCD

как когда-либо, если я использую "второй", я только получаю EF, но мне нужен результат, чтобы быть ABDFE

5
задан Johannes Stadler 16 February 2015 в 11:06
поделиться

3 ответа

Я получаю EBFAD с небольшой модификацией вашего файла xsl. Ключ в том, что если вы используете ключ для поиска первого узла с этим содержимым под заданным корневым элементом , тогда ключ должен быть специфическим для корневого элемента. Я изменил xsl: key на:

<xsl:key name="item-by-value" match="something"
 use="concat(normalize-space(.), ' ', generate-id(./ancestor::root))"/>

Тогда тест xsl: if станет:

<xsl:if test="generate-id() = generate-id(key('item-by-value', 
                  concat(normalize-space(.), ' ', generate-id(./ancestor::root))))">
2
ответ дан 15 December 2019 в 00:54
поделиться

Думаю, вы довольно близки. Но вам нужно только первое значение ключа по каждому значению, которое имеет правильный корень в качестве родителя:

<xsl:for-each select="key('rootkey','second')">
    <xsl:variable name="root" select="generate-id()" />
    <xsl:for-each select="item/something">
        <xsl:sort order="ascending" select="." data-type="text"/>
        <xsl:if test="generate-id() = generate-id(key('item-by-value', .)[generate-id(ancestor::root)=$root][1])">
            <xsl:value-of select="."/>
        </xsl:if>
    </xsl:for-each>
</xsl:for-each>
0
ответ дан 15 December 2019 в 00:54
поделиться

Это случай, когда вы должны использовать составной ключ.

Это преобразование :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:key name="kSomethingByNameAndVal" match="something"
  use="concat(../../name, '+', .)"/>

 <xsl:template match="/">
   <xsl:for-each select="*/*">
     <xsl:for-each select=
      "item/something
             [generate-id()
             =
              generate-id(key('kSomethingByNameAndVal',
                               concat(../../name, '+', .)
                              )
                          )
             ]
      ">

       <xsl:value-of select="."/>
     </xsl:for-each>
     <xsl:text>&#xA;</xsl:text>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

при правильном применении к предоставленному XML-документу дает желаемый результат :

ABCD

EBFAD

2
ответ дан 15 December 2019 в 00:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: