简体   繁体   English

C#xml读/写/ xpath而不使用XmlDocument

[英]C# xml read/write/xpath without using XmlDocument

I am refactoring some code in an existing system. 我正在重构现有系统中的一些代码。 The goal is to remove all instances of the XmlDocument to reduce the memory footprint. 目标是删除XmlDocument的所有实例以减少内存占用。 However, we use XPath to manipulate the xml when certain rules apply. 但是,当某些规则适用时,我们使用XPath来操作xml。 Is there a way to use XPath without using a class that loads the entire document into memory? 有没有办法使用XPath而不使用将整个文档加载到内存中的类? We've replaced all other instances with XmlTextReader, but those only worked because there is no XPath and the reading is very simple. 我们已经用XmlTextReader替换了所有其他实例,但那些只能工作,因为没有XPath并且读取非常简单。

Some of the XPath uses values of other nodes to base its decision on. 一些XPath使用其他节点的值来作出决定。 For instance, the value of the message node may be based on the value of the amount node, so there is a need to access multiple nodes at one time. 例如,消息节点的值可以基于量节点的值,因此需要一次访问多个节点。

If your XPATH expression is based on accessing multiple nodes, you're just going to have to read the XML into a DOM. 如果您的XPATH表达式基于访问多个节点,那么您只需将XML读入DOM即可。 Two things, though. 但有两件事。 First, you don't have to read all of it into a DOM, just the part you're querying. 首先,您不必将所有内容都读入DOM,只需要查询您正在查询的部分。 Second, which DOM you use makes a difference; 其次,你使用哪个DOM会产生影响; XPathDocument is read-only and tuned for XPATH query speed, unlike the more general purpose but expensive XmlDocument. XPathDocument是只读的并且针对XPATH查询速度进行了调整,这与更通用但昂贵的XmlDocument不同。

I supose that using System.Xml.Linq.XDocument is also prohibited? 我认为使用System.Xml.Linq.XDocument也是禁止的吗? Otherwise, it would be a good choice, as it is faster than XmlDocument (as I remember). 否则,它将是一个不错的选择,因为它比XmlDocument更快(我记得)。

Supporting XPath means supporting queries like: 支持XPath意味着支持以下查询:

//address[/states/state[@code=current()/@code]='California']

or 要么

//item[@id != preceding-sibling/item/@id]

which require the XPath processor to be able to look everywhere in the document. 这要求XPath处理器能够在文档中的任何位置查找。 You're not going to find a forward-only XPath processor. 你不会找到一个只有前向的XPath处理器。

The way to do this is to use XPathDocument, which can take a stream - therefore you can use StringReader. 这样做的方法是使用XPathDocument,它可以获取流 - 因此您可以使用StringReader。

This returns the value in a forward read way without the overhead of loading the whole XML DOM into memory with XmlDocument. 这将以正向读取方式返回值,而不会产生使用XmlDocument将整个XML DOM加载到内存中的开销。

Here is an example which returns the value of the first node that satisfies the XPath query: 下面是一个示例,它返回满足XPath查询的第一个节点的值:

public string extract(string input_xml)
    {
        XPathDocument document = new XPathDocument(new StringReader(input_xml));
        XPathNavigator navigator = document.CreateNavigator();
        XPathNodeIterator node_iterator = navigator.Select(SEARCH_EXPRESSION);
        node_iterator.MoveNext();
        return node_iterator.Current.Value;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM