2010-04-30 6 views
1

это получить еще более сложным :)XSL уникальных значений на узел в положение

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

теперь:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<roots> 
    <root> 
      <name>first</name> 
      <item> 
       <something>A</something> 
       <something>A</something> 
      </item> 
      <item> 
       <something>B</something> 
       <something>A</something> 
      </item> 
      <item> 
       <something>C</something> 
       <something>P</something> 
      </item> 
      <item> 
       <something>A</something> 
       <something>L</something> 
      </item> 
      <item> 
       <something>A</something> 
       <something>A</something> 
      </item> 
      <item> 
       <something>B</something> 
       <something>A</something> 
      </item> 
      <item> 
       <something>D</something> 
       <something>A</something> 
      </item> 
    </root> 
    <root> 
      <name>second</name> 
      <item> 
       <something>E</something> 
       <something>A</something> 
      </item> 
      <item> 
       <something>B</something> 
       <something>A</something> 
      </item> 
      <item> 
       <something>F</something> 
       <something>A</something> 
      </item> 
      <item> 
       <something>A</something> 
       <something>A</something> 
      </item> 
      <item> 
       <something>A</something> 
       <something>A</something> 
      </item> 
      <item> 
       <something>B</something> 
       <something>H</something> 
      </item> 
      <item> 
       <something>D</something> 
       <something>G</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="concat(normalize-space(.), ' ', generate-id(./ancestor::root))"/> 
<xsl:key name="rootkey" match="root" use="name"/> 
    <xsl:template match="/"> 
<xsl:for-each select="key('rootkey','first')"> 
<xsl:for-each select="item/something[1]"> 
<xsl:sort /> 
    <xsl:if test="generate-id() = generate-id(key('item-by-value', 
        concat(normalize-space(.), ' ', generate-id(./ancestor::root))))"> 
    <xsl:value-of select="."/> 
</xsl:if> 
</xsl:for-each> 
<xsl:text>_________</xsl:text> 
<xsl:for-each select="item/something[2]"> 
<xsl:sort /> 
    <xsl:if test="generate-id() = generate-id(key('item-by-value', 
        concat(normalize-space(.), ' ', generate-id(./ancestor::root))))"> 
    <xsl:value-of select="."/> 
</xsl:if> 
</xsl:for-each> 
</xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

с этим XSL я получаю ABCD_________LP где результат я нужен ABCD_________ALP

какие-либо идеи?

+0

(+1). См. Мой ответ для простой модификации решения, которое я представил вашему предыдущему вопросу. Это так просто. :) –

+0

@Nathan - Можете ли вы использовать xslt 2.0? Если да, то какой процессор вы используете? (Я не мог найти ваш другой вопрос, извините, если это было рассмотрено в этом.) –

+0

нет, я могу использовать только xslt 1.0, и я использую Xalan –

ответ

1

Еще раз, проблема в том, что если вы хотите, чтобы сказать: « первый узел с этим контентом под этим корнем , появляющийся в этой позиции в узле item ", тогда вам нужно добавить« позицию в узле item »к ключу. Вы можете сделать это при помощи двух отдельных ключей, так как решение Dimitre в делает, или изменить свой ключ:

use="concat(normalize-space(.), ' ', 
    count(./preceding-sibling::something), ' ', generate-id(./ancestor::root))"/> 

А затем сделать ваши два тестовых выражения выглядеть следующим образом:

<xsl:if test="generate-id() = generate-id(key('item-by-value', 
       concat(normalize-space(.), ' 0 ', generate-id(./ancestor::root))))"> 

и:

<xsl:if test="generate-id() = generate-id(key('item-by-value', 
       concat(normalize-space(.), ' 1 ', generate-id(./ancestor::root))))"> 
+0

Разумный. Мне не нравится делать ключи «слишком сложными», поэтому я использую два простых ключа. –

+0

Удивительные благодарности! –

1

Просто небольшая модификация моего ответа на ваш предыдущий вопрос, и у вас его есть!

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

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

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

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

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

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

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

Когда это преобразование применяется на прилагаемом документе XML, разыскиваемого, правильные результаты получают:

ABCD 
APL 
EBFAD 
AHG 
+0

Мы должны прекратить встречу, как это ... –

+0

@ Daniel- Мартин: ?????? –

+0

О, это еще раз: вопрос от того же парня о xsl, те же два человека отвечают, снова ваш ответ приходит, когда я печатаю мой, и ответы, которые каждый из нас дал на этот вопрос, очень похожи на то, что каждый из нас дал свой предыдущий вопрос. –

0

Я знаю, что вы ограничены XSLT 1.0, и вы используете Xalan, но я собираюсь добавить этот ответ на всякий случай, если он может помочь кому-то другому выполнить поиск в будущем. (Это может использовать XSLT 2.0.) Надеюсь, вы не против.

Кроме того, я использую Saxon-HE 9.2.0.6 для процессора.

Вот таблица стилей:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="text"/> 

    <xsl:template match="/roots"> 
     <xsl:for-each select="root"> 
     <xsl:value-of select="distinct-values(item/something[1])"/>___<xsl:value-of select="distinct-values(item/something[2])"/> 
     <xsl:text>&#xA;</xsl:text> 
     </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 

Вот вывод с помощью XML:

A B C D___A P L 
E B F A D___A H G 

Если вы хотите, чтобы лишить места от выхода, вы можете поместить вывод в переменную, а затем используйте replace, чтобы удалить пробелы. (Кто-нибудь знает лучший способ?)

Stylesheet:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="text"/> 

    <xsl:template match="/roots"> 
     <xsl:variable name="output"> 
     <xsl:for-each select="root"> 
      <xsl:value-of select="distinct-values(item/something[1])"/>___<xsl:value-of select="distinct-values(item/something[2])"/> 
      <xsl:text>&#xA;</xsl:text> 
     </xsl:for-each> 
     </xsl:variable> 
     <xsl:value-of select="replace($output,' ','')"/> 
    </xsl:template> 

</xsl:stylesheet> 

Выход:

ABCD___APL 
EBFAD___AHG 
+0

Я не против его хорошо иметь ссылку :) –

Смежные вопросы