使用xslt 1.0从两个不同的父标签中查找不同的元素

时间:2018-03-16 11:08:23

标签: xml xslt

我试图仅使用XSLT 1.0从以下示例XML中的两个不同父节点中查找不同的值。我需要的是通过将整数作为参数传递为每个<one>节点调用的模板。 <vln>标识每个<one>节点

输入:

   <?xml version="1.0" encoding="UTF-8"?>
   <filename>
     <root>
       <vln>56837073</vln>
       <one>
         <vln>1233213427</vln>
         <Maddress>
           <address>
             <state>ak</state>
           </address>
         </Maddress>
         <Maddress>
           <address>
             <state>vr</state>
           </address>
         </Maddress>
         <co>
           <Maddress>
             <address>
               <state>fg</state>
             </address>
           </Maddress>
           <Maddress>
             <address>
               <state>ak</state>
             </address>
           </Maddress>
         </co>
       </one>
       <one>
         <vln>6785475239</vln>
         <Maddress>
           <address>
             <state>pp</state>
           </address>
         </Maddress>
         <Maddress>
           <address>
             <state>fg</state>
           </address>
         </Maddress>
         <co>
           <Maddress>
             <address>
               <state>fg</state>
             </address>
           </Maddress>
           <Maddress>
             <address>
               <state>ak</state>
             </address>
           </Maddress>
         </co>
       </one>
     </root>
   </filename>

输出: 1.ak,vr,fg

2.pp,fg,ak

3 ....继续取决于<one>个节点

我尝试了各种教程后理解的所有方法。我所取得的是使用http://www.jenitennison.com/xslt/grouping/muenchian.html找到单独的父级不同的值,但是当合并时我不知道。帮助我解决这个问题。

我的代码:

<xsl:key name="product" match="one/Maddress/address/state/text()" use="." />
<xsl:template match="one">
          <xsl:for-each select="one/Maddress/address/state/text()[generate-id() = generate-id(key('product',.)[1])]">
              <xsl:value-of select="."/>
              <text> </text>
          </xsl:for-each>

<xsl:key name="product2" match="one/co/Maddress/address/state/text()" use="." />        
<xsl:template match="two">
          <xsl:for-each select="one/co/Maddress/address/state/text()[generate-id() = generate-id(key('product2',.)[1])]">
              <xsl:value-of select="."/>
              <text> </text>
          </xsl:for-each>

这里调用一个和两个模板来检查来自两个不同父节点的不同值。 达到产量:

1.ak,vr,fg,ak
2.pp,fg,fg,ak

2 个答案:

答案 0 :(得分:0)

如果您的要求是文字,那么您可以使用以下代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:output method="text" />

    <xsl:template match="/">
        <xsl:value-of select="distinct-values(//state)" separator=", "/>
    </xsl:template>


</xsl:stylesheet>

答案 1 :(得分:0)

您正在尝试为每个one元素获取不同的状态。这意味着您需要使用连锁密钥

<xsl:key name="product"  match="state" use="concat(ancestor::one/vln, '|', .)" />

这假定vln对于每个one节点都是唯一的。

然后,在每个one节点内,您将获得如下所示的不同状态:

<xsl:for-each select=".//state[generate-id() = generate-id(key('product', concat(ancestor::one/vln, '|', .))[1])]">

试试这个XSLT

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

<xsl:output method="text" />
<xsl:key name="product"  match="state" use="concat(ancestor::one/vln, '|', .)" />

<xsl:template match="/*">
  <xsl:apply-templates select="root/one" />
</xsl:template> 

<xsl:template match="one">
  <xsl:value-of select="vln" />
    <xsl:text> </xsl:text>
    <xsl:for-each select=".//state[generate-id() = generate-id(key('product', concat(ancestor::one/vln, '|', .))[1])]">
      <xsl:value-of select="."/>
      <xsl:text> </xsl:text>
    </xsl:for-each>
  <xsl:text>&#10;</xsl:text>
</xsl:template>
</xsl:stylesheet>