通过使用 xpath 在 C# 中过滤现有文档来创建新的 XMLDocument

发布于 2024-09-26 22:40:52 字数 1678 浏览 5 评论 0原文

我遇到过这样的情况:我从外部公司收到 XML(文档)文件。我需要过滤文档以删除所有我不感兴趣的数据。 该文件大约 500KB,但会经常被请求。

让我们说以下文件:

<dvdlist>
  <dvd>
    <title>title 1</title>
    <director>directory 2</director>
    <price>1</price>
    <location>
      <city>denver</city>
    </location>
  </dvd>
  <dvd>
    <title>title 2</title>
    <director>directory 2</director>
    <price>2</price>
    <location>
      <city>london</city>
    </location>
  </dvd>
  <dvd>
    <title>title 3</title>
    <director>directory 3</director>
    <price>3</price>
    <location>
      <city>london</city>
    </location>
  </dvd>
</dvdlist>

我需要的只是根据 city = london 过滤文档,以便最终得到这个新的 XML 文档

<dvdlist>
  <dvd>
    <title>title 2</title>
    <director>directory 2</director>
    <price>2</price>
    <location>
      <city>london</city>
    </location>
  </dvd>
  <dvd>
    <title>title 3</title>
    <director>directory 3</director>
    <price>3</price>
    <location>
      <city>london</city>
    </location>
  </dvd>
</dvdlist>

我已经尝试过以下

XmlDocument doc = new XmlDocument();
doc.Load(@"C:\Development\Website\dvds.xml");
XmlNode node = doc.SelectSingleNode("dvdlist/dvd/location/city[text()='london']");

任何帮助或链接,

谢谢

I have a situation where I receive an XML (document) file from an external company. I need to filter the document to remove all data I am not interested in.
The file is about 500KB but will be requested very often.

let say the following file:

<dvdlist>
  <dvd>
    <title>title 1</title>
    <director>directory 2</director>
    <price>1</price>
    <location>
      <city>denver</city>
    </location>
  </dvd>
  <dvd>
    <title>title 2</title>
    <director>directory 2</director>
    <price>2</price>
    <location>
      <city>london</city>
    </location>
  </dvd>
  <dvd>
    <title>title 3</title>
    <director>directory 3</director>
    <price>3</price>
    <location>
      <city>london</city>
    </location>
  </dvd>
</dvdlist>

What I need is simply filter the document based on the city = london in order to end up with this new XML document

<dvdlist>
  <dvd>
    <title>title 2</title>
    <director>directory 2</director>
    <price>2</price>
    <location>
      <city>london</city>
    </location>
  </dvd>
  <dvd>
    <title>title 3</title>
    <director>directory 3</director>
    <price>3</price>
    <location>
      <city>london</city>
    </location>
  </dvd>
</dvdlist>

I have tried the following

XmlDocument doc = new XmlDocument();
doc.Load(@"C:\Development\Website\dvds.xml");
XmlNode node = doc.SelectSingleNode("dvdlist/dvd/location/city[text()='london']");

Any help or links will appreciate

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

李白 2024-10-03 22:40:52

XPath 是一种选择表达式语言——它从不修改它所操作的 XML 文档

因此,为了获得所需的新 XML 文档,您需要使用 XML DOM(不推荐)或对 XML 文档应用 XSLT 转换。后者是推荐的方法,因为 XSLT 是一种专门为树转换而设计的语言。

在 .NET 中,可以使用 XslCompiledTransform 及其 Transform() 方法。在相关 MSDN 文档中了解有关这些内容的更多信息

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="dvd[not(location/city='london')]"/>
</xsl:stylesheet>

在这里,您可以找到完整的代码示例,如何以 XmlDocument 形式获取转换结果(或者如果需要,以 XDocument 形式) 。

XPath is a selection expression language -- it never modifies the XML document(s) it operates on.

Therefore, in order to obtain the desired new XML document, you need to either use XML DOM (not recommended) or apply an XSLT transformation to the XML document. The latter is the recommended way to go, since XSLT is a language especially designed for tree transformations.

In .NET one can use the XslCompiledTransform class and its Transform() method. Read more about these in the relevant MSDN documentation.

The XSLT transformation itself is extremely simple:

<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="dvd[not(location/city='london')]"/>
</xsl:stylesheet>

Here, you can find a complete code example how to obtain the result of the transformation as an XmlDocument (or if desired, as an XDocument).

眼眸里的快感 2024-10-03 22:40:52

下面是使用 LINQ to XML 的示例。

//load the document
var document = XDocument.Load(@"C:\Development\Website\dvds.xml");
//get all dvd nodes
var dvds = document.Descendants().Where(node => node.Name == "dvd");
//get all dvd nodes that have a city node with a value of "london"
var londonDVDs = dvds.Where(dvd => dvd.Descendants().Any(child => child.Name == "city" && child.Value == "london"));

Here's an example using LINQ to XML.

//load the document
var document = XDocument.Load(@"C:\Development\Website\dvds.xml");
//get all dvd nodes
var dvds = document.Descendants().Where(node => node.Name == "dvd");
//get all dvd nodes that have a city node with a value of "london"
var londonDVDs = dvds.Where(dvd => dvd.Descendants().Any(child => child.Name == "city" && child.Value == "london"));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文