如果条件为真,如何获取父节点及其所有子节点

时间:2015-11-24 13:59:38

标签: xml xslt-2.0

我有以下XML

<?xml version="1.0" encoding="utf-8"?>
<Students>
    <Student>
        <StdId value="1"/>
        <Name>a</Name>
        <Courses>
            <Course value="c1"/>
            <Course value="c2"/>
            <Course value="c3"/>
        </Courses>
    </Student>
    <Student>
        <StdId value="2" InActive="True"/>
        <Name>b</Name>
        <Courses>
            <Course value="c1"/>
            <Course value="c4"/>
            <Course value="c6"/>
        </Courses>
    </Student>
</Students>

我的XSLT代码是

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/">
        <xsl:result-document method="xml" href="file:///C:/Student_details.xml">
            <xsl:for-each select="Students/Student">
                <xsl:if test="(StdId[@InActive != 'True'])">
                    <xsl:copy-of select="Student"/>
                </xsl:if>
            </xsl:for-each>
        </xsl:result-document>
    </xsl:template>
</xsl:stylesheet>

我希望Student元素的子节点与StdId InActive="True"的位置不同。我的代码不会复制任何学生元素。

2 个答案:

答案 0 :(得分:1)

  1. 如果atributte根本不存在,则找不到该节点。

    <StdId value="1" InActive="False"/>

  2. 会被找到。

    您可以使用

     <xsl:if test="(StdId[@InActive!= 'True'] or StdId[not(@InActive)])">
    

    以便选择属性不存在的节点。

    1. <xsl:copy-of select="Student" />不起作用。 你可以用
      <xsl:copy-of select="node()" />选择当前节点(只是学生节点的内容)或<xsl:copy-of select="../Student" />,以便获取<Student> ... </Student>标签

答案 1 :(得分:1)

您可以将for-each选择中的XPath更改为仅迭代那些没有InActive = "True"属性的XPath:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/">
        <xsl:result-document method="xml">
            <xsl:for-each select="Students/Student[not(StdId/@InActive)]">
                    <xsl:copy-of select="."/>
            </xsl:for-each>
        </xsl:result-document>
    </xsl:template>
</xsl:stylesheet>

请注意,您的输出不是有效的XML,因为它没有根节点。

或者,您可以使用模板匹配,如下所示:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="Student[not(StdId/@InActive)]">
        <xsl:copy-of select="."/>
    </xsl:template>
    <xsl:template match="/">
        <xsl:result-document method="xml">
            <root>
                <xsl:apply-templates/>
            </root>
        </xsl:result-document>
    </xsl:template>
</xsl:stylesheet>

在我的第二个样式表中,我添加了一个根节点 - 这是我自己的本地测试,ymmv。

我已经在我的第一个样式表中编辑了XPath,因为你在评论中说过,当属性值为“True”时,该属性才会出现。