根据条件使用 key() 选择节点



>我遇到一种情况,我需要根据某些条件选择节点,然后应用Muenchian分组来获取唯一值。我使用的是 XSLT 1.0

<Parent>
    <Child>
        <A></A>
        <B></B>
        <C></C>
    </Child>
    <Child>
        <A></A>
        <B></B>
        <C></C>
    </Child>
    <Child>
        <A></A>
        <B></B>
        <C></C>
    </Child>
</Parent>

我有使用属性的条件是:如果 A 不为空,则使用 A。否则使用 B。

我想到了一个适用于节点 A 和 B 的固定宽度值的解决方案。因此,如果 A 和 B 的长度为 n,我可以执行以下操作:

<xsl:key name="groupKey" match="/Parent/Child" use="substring(concat(A,B),1,n)">

所以,如果 A 不存在,我可以使用 B。但是我一直无法弄清楚如何使用字符串长度()来导出 A 和 B 的可变长度的表达式。

如果你想使用concat()函数:

use="concat(A, B[not(string(../A)])"

如果空白是指空或仅空格,请使用

use="concat(A, B[not(normalize-space(../A)])"

最后,如果你真的想同时使用concat()substring() (这真的很棘手,所以我不推荐它):

concat(substring(A, 1 div string(A) or 0),
       substring(B, 1 div not(string(A)))
      )

下面是最后一种情况的完整示例,显示了对concat()调用返回的内容:

XML 文档

<t>
    <p>
        <A>xxx</A>
        <B>yyy</B>
    </p>
    <p>
        <A/>
        <B>zzz</B>
    </p>
</t>

转换(仅输出计算表达式的结果):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
  <xsl:template match="p">
    <xsl:value-of select=
    "concat(substring(A, 1 div string(A) or 0),
            substring(B, 1 div not(string(A)))
            )"/>
  </xsl:template>
</xsl:stylesheet>

产生想要的(正确)结果

xxx
zzz

怎么样:

use="A | B[not(string(../A))]"

这是另一个使用不同use的选项。

Example...

XML 输入

<Parent>
    <Child>
        <A>both</A>
        <B>both</B>
        <C>c</C>
    </Child>
    <Child>
        <A>a</A>
        <B></B>
        <C>c</C>
    </Child>
    <Child>
        <A></A>
        <B>b</B>
        <C>c</C>
    </Child>
</Parent>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:key name="child" match="Child" use="(A[string()]|B[string()])[1]"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="/*">
    <xsl:copy>
      <xsl:for-each select="Child[count(.|key('child',(A[string()]|B[string()])[1])[1])=1]">
        <group key="{(A[string()]|B[string()])[1]}">
          <xsl:apply-templates select="key('child',(A[string()]|B[string()])[1])"/>
        </group>
      </xsl:for-each>        
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

XML 输出

<Parent>
   <group key="both">
      <Child>
         <A>both</A>
         <B>both</B>
         <C>c</C>
      </Child>
   </group>
   <group key="a">
      <Child>
         <A>a</A>
         <B/>
         <C>c</C>
      </Child>
   </group>
   <group key="b">
      <Child>
         <A/>
         <B>b</B>
         <C>c</C>
      </Child>
   </group>
</Parent>

相关内容

  • 没有找到相关文章

最新更新