我有以下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代码复制了每件事。
答案 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"/>
的整数序列,这样您就不需要进行标记化调用。