XSL检查是否有任何子节点具有属性

时间:2012-01-27 20:47:07

标签: xml xslt

我有以下XML:

<record>
  <d989 p="Apples" t="Apples"/>
  <d990 p="Oranges" t="Bananas"/>
  <record_group_1>
    <d991 p="Mouse" t="Mouse and Cat"/>
    <d991 p="Dog" t="Dog and Cat"/>
  </record_group_1>
  <record_group_2>
    <d992 />
  </record_group_2>
 ...

我在确定节点是否有子节点之后使用以下XSL模板:

<xsl:template name="hasChildren">
  <tr>
    <td colspan="2" class="sectionTitle">
      <xsl:value-of select="translate(local-name(), '_', ' ')" />
    </td>
  </tr>
 ...

如何包装<xsl:template name="hasChildren">内容以确定有问题的节点是否有子节点,任何子节点是否具有p的属性。

我正在测试当前节点是否具有带<xsl:if test="@p">的p属性,但我不确定如果节点的子节点有p,我怎么能找到。

对于上面的XML示例,我想忽略<record_group_2>,因为它的子项不包含p的属性,而{I}我想要处理。

如果您需要更多说明,请告诉我......

2 个答案:

答案 0 :(得分:1)

这个表达式:

*[starts-with(local-name(), 'record_group_') and *[@p]]

...匹配名称以record_group_开头并且子元素具有p属性(*[@p])的所有元素。

目前尚不清楚您正在寻找的实际输出,但以下样式表应演示一般方法:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <!-- ignore other elements -->
    <xsl:template match="/*/*"/>
    <xsl:template match="*[starts-with(local-name(), 'record_group_') 
                              and *[@p]]">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

输出:

<record>
    <record_group_1>
        <d991 p="Mouse" t="Mouse and Cat"/>
        <d991 p="Dog" t="Dog and Cat"/>
    </record_group_1>
</record>

答案 1 :(得分:1)

  

我在确定节点后是否使用以下XSL模板   有孩子:

<xsl:template name="hasChildren">
    <tr>
        <td colspan="2" class="sectionTitle">
            <xsl:value-of select="translate(local-name(), '_', ' ')" />
        </td>
    </tr>  ...
</xsl:template>

此代码根本不执行所谓的操作!

I'm testing if the current node has an attribute of `p` with `<xsl:if test="@p">` but I'm not sure how I could find if the node's children has a `p`.

使用

*[@p]

此XPath表达式选择具有属性p的任何子元素(当前节点)。在test<xsl:if>的{​​{1}}属性中使用时,如果节点集非空且<xsl:when>,则选择的节点集将转换为布尔值:true() 1}}否则。

  

对于上面的XML示例,我想忽略false()   因为它的子元素不包含p的属性   <record_group_2>我想要处理

使用:只是上面的表达式。

这是一个完整且非常简单的简短转换,它只将那些具有<record_group_1>属性的top元素的子元素复制到输出中:

p

将此转换应用于提供的XML文档(更正为格式良好):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
  <xsl:copy>
   <xsl:copy-of select="*[*/@p]"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

想要的,正确的结果(不包含至少一个具有<record> <d989 p="Apples" t="Apples"/> <d990 p="Oranges" t="Bananas"/> <record_group_1> <d991 p="Mouse" t="Mouse and Cat"/> <d991 p="Dog" t="Dog and Cat"/> </record_group_1> <record_group_2> <d992 /> </record_group_2> </record> 属性的子元素的非顶级元素将被删除)生成

p