不使用XmlDocument的C# xml读取/写入/XPath

3
我正在重构现有系统中的一些代码。目标是删除所有XmlDocument实例以减少内存占用。但是,在某些规则适用时,我们使用XPath来操作xml。有没有一种方法可以在不使用将整个文档加载到内存的类的情况下使用XPath?我们已经用XmlTextReader替换了所有其他实例,但那些只能工作因为没有XPath并且读取非常简单。
其中一些XPath使用其他节点的值来基于其决策。例如,消息节点的值可能基于金额节点的值,因此需要同时访问多个节点。
4个回答

3
如果您的XPATH表达式是基于访问多个节点的,那么您只需要读取XML到DOM中。不过要注意两点。首先,您不必将全部内容都读入DOM中,只需要读取您要查询的部分即可。其次,使用哪种DOM会产生不同的效果;XPathDocument是只读的,并针对XPATH查询速度进行了优化,而不像更通用但代价昂贵的XmlDocument。

1

我猜使用 System.Xml.Linq.XDocument 也是被禁止的吧?否则,它会是一个不错的选择,因为它比XmlDocument更快(就我所记得的而言)。


2
一切都比XmlDocument快。:-) - Steven Sudit
1
然而,由于它允许更改XML,因此可能比XPathDocument慢。 - Steven Sudit
是的,可能是这样,但标题指出它需要读/写/XPath,所以我猜XPathDocument不行。 - Philippe
我不反对读取xml并写入另一个xml。只是这样做不够优雅。 - Brian

0

实现这个的方法是使用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;
    }

0

支持XPath意味着支持像这样的查询:

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

或者

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

这需要XPath处理器能够在文档中随处查找。你不会找到一个仅向前的XPath处理器。


我的答案展示了如何使用XPathDocument以单向方式处理XPath。 - Alexis
如果搜索查询导致反向搜索(比如我发布的 XPath 中),会发生什么? - Robert Rossney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接