如果条件为真,如何复制除1之外的所有节点

时间:2015-11-26 11:16:16

标签: xml xslt xslt-2.0

我有以下XML。

     <?xml version="1.0" encoding="utf-8"?>
     <Students>
      <Student>
       <StdId value="1"/>
       <Name>a</Name>
       <Courses>
         <Course Id="2" value="c1"/>
        <Course Id="3" value="c2"/>
        <Course Id="4" value="c3"/>
       </Courses>
       <Addresses>
         <Address Id="2" type="permanent">
            <address1>my address</address1>
        </Address>
        <Address Id="4" type="Temporary">
            <address1>my address temp address</address1>
        </Address>
       </Addresses>
      </Student>
      <Student>
       <StdId value="2" InActive="True"/>
       <Name>b</Name>
       <Courses>
         <Course Id="2" value="c1"/>
        <Course Id="3" value="c4"/>
        <Course Id="5" value="c6"/>
       </Courses>
       <Addresses>
        <Address Id="2" type="permanent">
            <address1>my address</address1>
        </Address>
       </Addresses>
      </Student>
     </Students>

我的xslt是

     <?xml version="1.0" encoding="utf-8"?>
     <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:variable name="list" >1 4 6 15</xsl:variable> 
     <xsl:template match="/">       
    <xsl:result-document method="xml" href="file:///C:/Student_details.xml">
        <xsl:for-each select="Students/Student">                
            <xsl:variable name="vv1" select="Addresses/Address/@id" /> 
            <xsl:variable name="vv2" select="Courses/Course/@id" /> 
            <xsl:choose>
                <xsl:when test="contains($list, $vv1)">
                    <xsl:copy-of select=". except(Addresses)" />
                </xsl:when>
                <xsl:when test="contains($list, $vv2)">
                    <xsl:copy-of select=". except(Courses)" /> 
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy-of select="." />
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </xsl:result-document>
</xsl:template>

我想根据条件过滤一些节点。当地址@id值在列表中时,然后复制除地址及其子项之外的所有内容。当课程@id值在列表中时,然后复制除课程及其子节点之外的所有内容。如果上述条件均不属实,则复制所有内容。我的XSLT代码复制了每件事。

1 个答案:

答案 0 :(得分:1)

请注意,您的输入示例具有Id属性,而不是id属性,因此在XPath中选择您需要的输入@Id。我不确定我理解您的要求,假设您确实要删除任何Courses,如果在列表中找到任何Addresses,您只需使用

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

    <xsl:variable name="list" >1 4 6 15</xsl:variable>
    <xsl:variable name="ids" select="tokenize($list, '\s+')"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Student/Courses[Course/@Id = $ids] | Student/Addresses[Address/@Id = $ids]"/>
</xsl:transform>

对于您提供的输入样本,会创建结果

<?xml version="1.0" encoding="UTF-8"?>
<Students>
   <Student>
      <StdId value="1"/>
      <Name>a</Name>
   </Student>
   <Student>
      <StdId value="2" InActive="True"/>
      <Name>b</Name>
      <Courses>
         <Course Id="2" value="c1"/>
         <Course Id="3" value="c4"/>
         <Course Id="5" value="c6"/>
      </Courses>
      <Addresses>
         <Address Id="2" type="permanent">
            <address1>my address</address1>
         </Address>
      </Addresses>
   </Student>
</Students>

如果要显式创建结果文档,请使用例如

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

    <xsl:variable name="list" >1 4 6 15</xsl:variable>
    <xsl:variable name="ids" select="tokenize($list, '\s+')"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/">
        <xsl:result-document>
            <xsl:apply-templates/>
        </xsl:result-document>
    </xsl:template>
    <xsl:template match="Student/Courses[Course/@Id = $ids] | Student/Addresses[Address/@Id = $ids]"/>
</xsl:transform>

请注意,原始代码中的<xsl:variable name="list" >1 4 6 15</xsl:variable>实际上不是一个列表,而是一个值序列,因此我使用<xsl:variable name="ids" select="tokenize($list, '\s+')"/>以编程方式创建序列。但是,也可以简单地将变量值定义为执行<xsl:variable name="ids" select="1, 4, 6, 15"/>的整数序列,这样您就不需要进行标记化调用。