我正在重构现有系统中的一些代码。目标是删除 XmlDocument 的所有实例以减少内存占用。但是,当某些规则适用时,我们使用 XPath 来操作 xml。有没有办法在不使用将整个文档加载到内存中的类的情况下使用 XPath?我们已经用 XmlTextReader 替换了所有其他实例,但这些实例之所以有效,是因为没有 XPath 并且读取非常简单。
一些 XPath 使用其他节点的值作为其决策的基础。例如,消息节点的值可能基于数量节点的值,因此需要一次访问多个节点。
我正在重构现有系统中的一些代码。目标是删除 XmlDocument 的所有实例以减少内存占用。但是,当某些规则适用时,我们使用 XPath 来操作 xml。有没有办法在不使用将整个文档加载到内存中的类的情况下使用 XPath?我们已经用 XmlTextReader 替换了所有其他实例,但这些实例之所以有效,是因为没有 XPath 并且读取非常简单。
一些 XPath 使用其他节点的值作为其决策的基础。例如,消息节点的值可能基于数量节点的值,因此需要一次访问多个节点。
如果您的 XPATH 表达式基于访问多个节点,那么您只需要将 XML 读入 DOM。不过有两件事。首先,您不必将所有内容都读入 DOM,只需将要查询的部分读入即可。其次,您使用的 DOM 会有所不同;XPathDocument 是只读的,并针对 XPATH 查询速度进行了调整,这与更通用但价格昂贵的 XmlDocument 不同。
我想也禁止使用System.Xml.Linq.XDocument ?否则,这将是一个不错的选择,因为它比 XmlDocument 快(我记得)。
支持 XPath 意味着支持如下查询:
//address[/states/state[@code=current()/@code]='California']
或者
//item[@id != preceding-sibling/item/@id]
这要求 XPath 处理器能够查看文档中的任何位置。您不会找到只进的 XPath 处理器。
做到这一点的方法是使用 XPathDocument,它可以采用流 - 因此您可以使用 StringReader。
这会以向前读取的方式返回值,而无需使用 XmlDocument 将整个 XML DOM 加载到内存中。
下面是一个示例,它返回满足 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;
}