XSLT 通过仅过滤标记值等于的那些节点来创建另一个 XML
Posted
技术标签:
【中文标题】XSLT 通过仅过滤标记值等于的那些节点来创建另一个 XML【英文标题】:XSLT to create another XML by filtering only those node where tag value equals 【发布时间】:2021-08-07 12:32:24 【问题描述】:我想在下面的文档示例中借助 XSLT 创建另一个 XML。这个想法是让所有学生的个人资料>城市是[PNH],无论他们的起源>地址>城市是什么。我知道在 XSLT 的帮助下,我们可以过滤掉并只复制我们希望在新 XML 文档中包含的内容。
<?xml version="1.0" encoding="utf-8"?>
<Class>
<Student>
<Profile>
<Name>G1</Name>
<City>PNH</City>
<RegDate>2020-06-20</RegDate>
</Profile>
<Origin>
<Address>
<City>REP</City>
</Address>
</Origin>
</Student>
<Student>
<Profile>
<Name>G4</Name>
<City>REP</City>
<RegDate>2020-06-20</RegDate>
</Profile>
<Origin>
<Address>
<City>PNH</City>
</Address>
</Origin>
</Student>
<Student>
<Profile>
<Name>G3</Name>
<City>PNH</City>
<RegDate>2020-06-20</RegDate>
</Profile>
<Origin>
<Address>
<City>PNH</City>
</Address>
</Origin>
</Student>
<Student>
<Profile>
<Name>G5</Name>
<City>KOS</City>
<RegDate>2020-06-20</RegDate>
</Profile>
<Origin>
<Address>
<City>PNH</City>
</Address>
</Origin>
</Student>
</Class>
我只想录取那些 Profile -> City 等于 'PNH' 的学生,这应该是最终的 XML 结果
<?xml version="1.0" encoding="utf-8"?>
<Class>
<Student>
<Profile>
<Name>G1</Name>
<City>PNH</City>
<RegisterDate>2020-06-20</RegisterDate>
</Profile>
<Origin>
<Address>
<City>REP</City>
</Address>
</Origin>
</Student>
<Student>
<Profile>
<Name>G3</Name>
<City>PNH</City>
<RegisterDate>2020-06-20</RegisterDate>
</Profile>
<Origin>
<Address>
<City>PNH</City>
</Address>
</Origin>
</Student>
</Class>
我已经尝试过了,但它仍然可以获取所有学生,但删除了城市不是 PNH 的 Profile Tag 中的数据
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Profile[not(City = 'PNH')]"/>
【问题讨论】:
【参考方案1】:如果你想排除满足某个条件的Student
s,那么你的模板必须匹配Student
元素:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Student[not(Profile/City = 'PNH')]"/>
</xsl:stylesheet>
或者,您可以这样做:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/Class">
<xsl:copy>
<xsl:copy-of select="Student[Profile/City = 'PNH']"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
【讨论】:
太好了,它现在可以工作了。将属性 xsi:nil="true" 添加到标签时还有一个问题。初始加载文档时,C# 会在新 XPathDocument(sXmlPath) 上引发“xsi”未定义前缀的错误捕获。我想我应该再写一篇文章。 我也这么认为。以上是关于XSLT 通过仅过滤标记值等于的那些节点来创建另一个 XML的主要内容,如果未能解决你的问题,请参考以下文章