【问题标题】:Create a new XMLDocument by filtering an existing document in c# using xpath通过在 c# 中使用 xpath 过滤现有文档来创建新的 XMLDocument
【发布时间】:2011-04-23 06:11:48
【问题描述】:

我收到了来自外部公司的 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']");

任何帮助或链接将不胜感激

谢谢

【问题讨论】:

  • 是否有您不想使用 Linq to XML 的特定原因?
  • 你真的遇到什么问题了吗?你尝试了一些东西;成功了吗?
  • @DoctaJonez。不,没有。如果 Linq 更适合我会很高兴。
  • 好问题,+1。请参阅我的答案以获得简单而完整的解决方案。 :)

标签: c# linq xslt xpath xmldocument


【解决方案1】:

这是一个使用 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"));

【讨论】:

  • 感谢 DoctaJonez。我在下面完成了本教程,因为我是 Linq download.microsoft.com/download/c/f/b/… 的新手,并且有以下代码可以让我获得所需的列表。字符串路径 = @"C:\Development\Website\sp.xml"; var dvds = from d in XElement.Load(path).Elements("dvd") where d.Element("location").Element("city").Value == "london" select d;我的问题是如何将数据作为新的 XmlDocument
  • 如果您使用 LINQ to XML(即 XDocument),那么您应该创建一个新的 XDocument,而不是 XmlDocument。创建一个新的 XDocument 很简单:XDocument input = XDocument.Load("input.xml"); XDocument output = new XDocument(new XElement(input.Root.Name, input.Root.Elements("dvd").Where(d =&gt; (string)d.Element("location").Element("city") == "london"))); output.Save("output.xml");.
  • 谢谢马丁。这很有用。
【解决方案2】:

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

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

在 .NET 中可以使用XslCompiledTransform 及其Transform() 方法。在 relevant MSDN documentation 中了解更多信息。

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>

Here,您可以找到完整的代码示例,如何将转换结果作为 XmlDocument(或者如果需要,作为 XDocument)获取。

【讨论】:

  • 谢谢迪米特。我会试一试,然后告诉你。干杯
  • 再次感谢 Dimitre。最后我接受了你的建议。确实,当了解 xpath 时,XSLT 很容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-07
  • 2022-01-17
  • 1970-01-01
  • 2019-12-14
  • 2014-04-25
  • 2010-12-10
相关资源
最近更新 更多