gpt4 book ai didi

c# - 尝试使用 XPath 过滤 XML

转载 作者:行者123 更新时间:2023-11-30 17:21:01 27 4
gpt4 key购买 nike

我正在尝试使用 XPath 过滤 XML 文件。我使用的 XPath 肯定会过滤到我想要的数据,但我只是不确定如何过滤整个文件。

这是示例 XML 文件:

<fields>
<field name='F'>
<field name='0'><value>F.0 stuff</value></field>
<field name='1'><value>F.1 stuff</value></field>
<field name='2'><value>F.2 stuff</value></field>
</field>
<field name='B'>
<field name='0'><value>B.0 stuff</value></field>
<field name='1'><value>B.1 stuff</value></field>
<field name='2'><value>B.2 stuff</value></field>
<field name='3'><value>B.3 stuff</value></field>
</field>
</fields>

这是期望的输出:

<fields>
<field name='F'>
<field name='1'><value>F.1 stuff</value></field>
<field name='2'><value>F.2 stuff</value></field>
</field>
<field name='B'>
<field name='3'><value>B.3 stuff</value></field>
</field>
</fields>

解决方案不一定非得用 XPath 解决,但由于这是一个 .NET 应用程序,.NET API 将不胜感激!可以将以下代码剪切并粘贴到 LINQPad 中,无需编辑以查看我正在尝试做什么。

var doc = XDocument.Parse(@"
<fields>
<field name='F'>
<field name='0'><value>F.0 stuff</value></field>
<field name='1'><value>F.1 stuff</value></field>
<field name='2'><value>F.2 stuff</value></field>
</field>
<field name='B'>
<field name='0'><value>B.0 stuff</value></field>
<field name='1'><value>B.1 stuff</value></field>
<field name='2'><value>B.2 stuff</value></field>
<field name='3'><value>B.3 stuff</value></field>
</field>
</fields>");
doc.Dump("Original XML");

var xpath = "//fields/field[@name='F']/field[@name='1' or @name='2'] | //fields/field[@name='B']/field[@name='3']";
doc.XPathSelectElements(xpath).Dump("XPath Combined");

var desired = XDocument.Parse(@"
<fields>
<field name='F'>
<field name='1'><value>F.1 stuff</value></field>
<field name='2'><value>F.2 stuff</value></field>
</field>
<field name='B'>
<field name='3'><value>B.3 stuff</value></field>
</field>
</fields>");
desired.Dump("Desired Filtered XML");

编辑:我完全错过了 XML 转换 - 感谢您提供的解决方案!您可以将以下解决方案粘贴到 LINQPad 中以查看它是否正常工作:

var filterString = @"@name=""F""]/field[@name=""0""]  | field[@name=""B""]/field[not(@name=""3"")";
var xslFmt = @"
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output omit-xml-declaration='yes' indent='yes'/>

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

<xsl:template match=
'field[{0}]
'/>
</xsl:stylesheet>";
var xslMarkup = string.Format(xslFmt, filterString);

var xmlTree = XDocument.Parse(@"
<fields>
<field name='F'>
<field name='0'><value>F.0 stuff</value></field>
<field name='1'><value>F.1 stuff</value></field>
<field name='2'><value>F.2 stuff</value></field>
</field>
<field name='B'>
<field name='0'><value>B.0 stuff</value></field>
<field name='1'><value>B.1 stuff</value></field>
<field name='2'><value>B.2 stuff</value></field>
<field name='3'><value>B.3 stuff</value></field>
</field>
</fields>");
xmlTree.Dump("Original XML");

// Code from MSDN: http://msdn.microsoft.com/en-us/library/bb675186.aspx
var newTree = new XDocument();
using (var writer = newTree.CreateWriter()) {
// Load the style sheet.
var xslt = new XslCompiledTransform();
xslt.Load(XmlReader.Create(new StringReader(xslMarkup)));

// Execute the transform and output the results to a writer.
xslt.Transform(xmlTree.CreateReader(), writer);
}

newTree.Dump("Transformed XML");

最佳答案

XPath 是一种查询语言,不能用于生成修改后的 XML 文档

专门为此类转换设计的技术称为 XSLT

您可以使用 XDocument.CreateNavigator() 方法,然后使用 XslCompiledTransform.Transform() 的重载之一 方法进行转换。

XSLT 转换本身非常简单:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>

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

<xsl:template match=
"field[@name='F']/field[@name='0']
|
field[@name='B']/field[not(@name='3')]
"/>
</xsl:stylesheet>

当应用于提供的 XML 文档时,它会产生所需的正确结果:

<fields>
<field name="F">
<field name="1">
<value>F.1 stuff</value>
</field>
<field name="2">
<value>F.2 stuff</value>
</field>
</field>
<field name="B">
<field name="3">
<value>B.3 stuff</value>
</field>
</field>
</fields>

关于c# - 尝试使用 XPath 过滤 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3816764/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com