2012-01-27 105 views
3

我有下面的XML:XSL检查是否有子节点具有属性

<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。

我正在测试,如果当前节点具有p的属性<xsl:if test="@p">,但我不知道如何找到节点的孩子是否有p。

对于上面的XML示例,我想忽略<record_group_2>,因为它的子项不包含p的属性,而我想要处理的是<record_group_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。当在<xsl:if><xsl:when>test属性中使用时,如果节点集非空,则选择的节点集将转换为布尔型:true(),否则转换为布尔型:false()

对于XML上述例子我想忽略<record_group_2> 因为它的孩子不包含其中,如 <record_group_1>我想处理

使用 p的属性:只要上述表达。

这是一个完整的,非常简单和短期转型该副本输出只有顶件的那些孩子,有一个p属性:

<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> 

当这种变换的应用提供的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> 
</record> 

有用,正确ř esult 产生(不具有带p属性都将被删除至少一个孩子非顶级元素):

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

这是伟大的,正是我一直在寻找。 – Matthew 2012-02-07 17:38:38

+0

@Matthew:不客气。 – 2012-02-07 18:38:48

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>