获取节点列表在XML文件中的其他位置找不到哪个子节点值

时间:2015-11-12 17:30:29

标签: xml xslt

我想为每项工作做以下事。

 <xsl:for-each select="DATA[not(SUB1 and SUB2) 
 or ((SUB1 or SUB2) and count(//PERSON[SUB1=current()/SUB1 and SUB2=current()/SUB2] )=0)]">

语法正确但不起作用。我尝试在current()之后添加一个点,但它也不起作用。

 <xsl:for-each select="DATA[not(SUB1 and SUB2) 
 or ((SUB1 or SUB2) and count(//PERSON[SUB1=current()/./SUB1 and SUB2=current()/./SUB2])=0 )]">

我觉得问题是current()。它也不适用于self::。我希望current()/SUB1引用DATA的子节点。

如果我从<xsl:for-each>删除测试并将其放入<xsl:if>之后,我可以使其正常工作。它不在for-each语句中。

<xsl:for-each select="DATA">
    <xsl:if test="not(SUB1 and SUB2) or ((SUB1 or SUB2) and count(//PERSON[SUB1=current()/SUB1 and SUB2=current()/SUB2])=0)">
         ....
    </xsl:if>
</xsl:for-each>

这是一个测试XML:

<ROOT>
    <PERSON>
        <SUB1>11</SUB1>
        <SUB2>AA</SUB2>
    </PERSON>
    <PERSON>
        <SUB1>22</SUB1>
        <SUB2>BB</SUB2>
    </PERSON>
    <DATA>
        <SUB1>99</SUB1>
        <SUB2>ZZ</SUB2>
    </DATA>
    <DATA>
        <SUB1>22</SUB1>
        <SUB2>BB</SUB2>
    </DATA>
    <DATA>
    </DATA>
</ROOT>

它应该选择这些<DATA>块,因为一个没有SUB子节点而另一个没有,但是没有人有这些SUB值:

    <DATA>
        <SUB1>99</SUB1>
        <SUB2>ZZ</SUB2>
    </DATA>
    <DATA>
    </DATA>

1 个答案:

答案 0 :(得分:1)

使用XSLT 2.0:

<xsl:template match="ROOT">
  <xsl:apply-templates select="DATA" />
</xsl:template>

<xsl:template
    match="DATA[empty(SUB1) and empty(SUB2)] |
           DATA[SUB1 or SUB2]
               [every $data in .
                 satisfies empty(/ROOT/PERSON[SUB1=$data/SUB1 and SUB2=$data/SUB2])]">
  <xsl:copy-of select="." />
</xsl:template>

<xsl:template match="DATA" />

使用XSLT 1.0或XSLT 2.0(并且可能对大量PERSON更有效):

<xsl:key name="person"
         match="PERSON"
         use="concat(SUB1, '&#xFFFC;', SUB2)" />

<xsl:template match="ROOT">
  <xsl:apply-templates select="DATA" />
</xsl:template>

<xsl:template
    match="DATA[not(SUB1) and not(SUB2)] |
           DATA[SUB1 or SUB2]
               [not(key('person', concat(SUB1, '&#xFFFC;', SUB2)))]">
  <xsl:copy-of select="." />
</xsl:template>

<xsl:template match="DATA" />