XSL唯一值每

问题描述:

位置

此得到更加复杂:)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)。查看我的答案,以便轻松修改我提供给您的上一个问题的解决方案。这很简单。 :) – 2010-04-30 16:20:33

+0

@Nathan - 你能使用xslt 2.0吗?如果是这样,你在用什么处理器? (我找不到你的其他问题;对不起,如果这是涵盖在那一个) – 2010-04-30 17:45:40

+0

不,我只能使用xslt 1.0,我使用Xalan – 2010-04-30 18:02:14

再次,问题是,如果你想要说的”第一个节点在此根目录下出现在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

合理。我讨厌让键“太复杂”,所以我使用了两个更简单的键。 – 2010-04-30 16:32:03

+0

真棒谢谢! – 2010-04-30 16:38:04

只是稍微修改了我对上一个问题的回答,你已经明白了!

<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

我们必须停止这样的会议...... – 2010-04-30 16:26:04

+0

@ Daniel-马丁:?????? – 2010-04-30 16:27:55

+0

哦,这又是一次:来自同一个人关于xsl的问题,同样的两个人回答,当我打我的时候,你的答案再次出现,我们每个人给出的答案都非常类似于每个人我们对他早先的问题给了。 – 2010-04-30 16:32:24

我知道您仅限于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去掉空格。 (任何人都知道更好的方法?)

样式表:

<?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

我不介意它很好有参考:) – 2010-04-30 20:12:29