从任意密钥路径中检索C#中的XML值

问题描述 投票:0回答:2

我有一个项目,我目前正在通过文档密钥中的任意/用户定义路径实现从XML文件读取值的支持。

例如,如果文档如下所示:

<information>
    <machine>
        <foo></foo>
        <name>
            test machine
        </name>
        <bar>spam</bar>
    </machine>
</information>

那么用户可能想要从name中的information/machine键中检索值。

有没有办法使用XDocument / XPath我可以查找用户想要的值而不知道/编码文档的架构?

我最初的想法是通过使用XElement项目的递归函数来完成文档,但我觉得应该有一个更简单/更清晰的解决方案,不需要我自己编写查找代码。

我也沿着这些方向尝试了一些东西

var doc = XDocument.Load("C:\Path\to\XML\file.xml");

// Split the parent keys string
XElement elem = doc.Root.XPathSelectElement("path/to/key");
if (elem != null && elem.Attribute("wantedKeyName") != null)
    replace = elem.Attribute("wantedKeyName").Value;

但是elem总是空的。我假设我在定义路径或使用XPathSelectElement的方式存在问题,但我还没有解决它。

c# xml xpath linq-to-xml
2个回答
0
投票
static XmlNode SearchNode(XmlNodeList nodeList, string nodeName)
{
    for (int i = 0; i < nodeList.Count; i++)
    {
        if (nodeList[i].Name == nodeName)
        {
            return nodeList[i];
        }

        if (nodeList[i].HasChildNodes)
        {
            XmlNode node = SearchNode(nodeList[i].ChildNodes, nodeName);
            if (node != null)
            {
                return node;
            }
        }
    }

    return null;
}

static XmlNodeList SearchNodeByPath(XmlNodeList nodeList, string xPath)
{
    for (int i = 0; i < nodeList.Count; i++)
    {
        var nodes = nodeList[i].SelectNodes(xPath);
        if (nodes != null && nodes.Count > 0)
        {
            return nodes;
        }

        if (nodeList[i].HasChildNodes)
        {
            XmlNodeList innerNodes = SearchNodeByPath(nodeList[i].ChildNodes, xPath);
            if (innerNodes != null && innerNodes.Count > 0)
            {
                return innerNodes;
            }
        }
    }

    return null;
}

这是使用方法:

    var node = SearchNode(doc.ChildNodes, "compiler");
    var node1 = SearchNodeByPath(doc.ChildNodes, "compilers/compiler");

0
投票

我发现我的解决方案使用XPathSelectElement是正确的方法,我只需要在path/to/key前加上//字符串。

我最终使用的以下代码执行此操作并剥离值外部周围的任何空格(如果值位于与开始标记不同的行上)。

// xml is a struct with the path to the parent node (path/to/key)
// and the key name to look up
// Split the parent keys string
XElement elem = doc.Root.XPathSelectElement("//" + xml.KeyPath);
if (elem != null && elem.Element(xml.Key) != null)
    replace = elem.Element(xml.Key).Value.Trim();
© www.soinside.com 2019 - 2024. All rights reserved.