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

时间:2010-10-09 16:58:54

标签: c# linq xslt xpath xmldocument

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

任何帮助或链接都会表示赞赏

谢谢

2 个答案:

答案 0 :(得分:2)

XPath是一种选择表达式语言 - 它永远不会修改它所运行的XML文档

因此,为了获得所需的新XML文档,您需要使用XML DOM(不推荐)或将XSLT转换应用于XML文档。后者是推荐的方法,因为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)获取。

答案 1 :(得分:0)

以下是使用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"));