根据条件

时间:2016-02-03 17:15:13

标签: xslt xslt-1.0

我有一种情况需要根据特定条件选择节点,然后应用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.但是我无法弄清楚如何使用string-length()来导出A和B的变量长度的表达式。任何想法?< / p>

3 个答案:

答案 0 :(得分:2)

如果您想使用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

答案 1 :(得分:1)

怎么样:

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

答案 2 :(得分:1)

这是另一个使用不同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>