如何在条件为真时复制除一个节点之外的所有节点
How to copy all the nodes except one when a condition is true
我得到了以下 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 值在列表中时,复制除地址及其子项之外的所有内容。当 Course @id 值在列表中时,复制除课程及其子节点之外的所有内容。当上述条件 none 为真时,复制所有内容。我的 XSLT 代码复制了所有内容。
请注意,您的输入示例具有 Id
属性,而不是 id
属性,因此在 select 的 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"/>
的整数序列,这样您就不需要标记化调用。
我得到了以下 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 值在列表中时,复制除地址及其子项之外的所有内容。当 Course @id 值在列表中时,复制除课程及其子节点之外的所有内容。当上述条件 none 为真时,复制所有内容。我的 XSLT 代码复制了所有内容。
请注意,您的输入示例具有 Id
属性,而不是 id
属性,因此在 select 的 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"/>
的整数序列,这样您就不需要标记化调用。