如何重写导航节点列表的代码

发布于 2024-10-06 10:04:07 字数 1487 浏览 8 评论 0原文

我刚刚编写了一些代码,在编写时我认为这将是搜索特定节点的一个很好的通用方法。当我完成时,我实际上意识到这是一团糟:D

public String sqlReading(String fileName, String path, String nodeId )
{
    XmlDocument doc = new XmlDocument();
    doc.Load(fileName);

    XmlNodeList names = doc.SelectNodes(path);
    foreach (XmlNode xmlDocSearchTerm in names)
    {
        //if the attribute of the node i start at is the same as where i am now
        if (xmlDocSearchTerm.Attributes.Item(0).Value.ToString().Equals(nodeId))
        {
            //get a list of all of its child nodes
            XmlNodeList childNodes = xmlDocSearchTerm.ChildNodes;

            foreach (XmlNode node in childNodes)
            {
                //if there is a node in here called gui display, go inside
                if (node.Name.Equals("GUIDisplay"))
                {
                    XmlNodeList list = node.ChildNodes;
                    //find the sqlsearchstring tag inside of here
                    foreach (XmlNode finalNode in list)
                    {
                        if (finalNode.Name.Equals("sqlSearchString"))
                        {
                            return node.InnerText;
                        }
                    }
                }
            }
        }
    }
    return "";
}

我打算做的是基于路径 - 我会开始检查该元素是否具有我正在寻找的 id,如果有,那么我想进入内部直到我到达深两层的 sqlsearchstring 标签,我才停止前进。我已经做到了,但这里的问题是,现在我似乎几乎硬编码了标签的路径,而不是在那里循环。我怎样才能改变我的代码来阻止我这样做?

在我看来,它是从第二个 foreach 开始出错的。

谢谢

I have just written some code, which as i was writing i thought, this is going to be a nice generic method for searching for a particular node. When i finished i actually realised it was a mess :D

public String sqlReading(String fileName, String path, String nodeId )
{
    XmlDocument doc = new XmlDocument();
    doc.Load(fileName);

    XmlNodeList names = doc.SelectNodes(path);
    foreach (XmlNode xmlDocSearchTerm in names)
    {
        //if the attribute of the node i start at is the same as where i am now
        if (xmlDocSearchTerm.Attributes.Item(0).Value.ToString().Equals(nodeId))
        {
            //get a list of all of its child nodes
            XmlNodeList childNodes = xmlDocSearchTerm.ChildNodes;

            foreach (XmlNode node in childNodes)
            {
                //if there is a node in here called gui display, go inside
                if (node.Name.Equals("GUIDisplay"))
                {
                    XmlNodeList list = node.ChildNodes;
                    //find the sqlsearchstring tag inside of here
                    foreach (XmlNode finalNode in list)
                    {
                        if (finalNode.Name.Equals("sqlSearchString"))
                        {
                            return node.InnerText;
                        }
                    }
                }
            }
        }
    }
    return "";
}

What i intended to do was based on a path - i would start and check to see if the element had the id i was looking for, if it did then i wanted to get inside there and not stop going until i got to the sqlsearchstring tag which was buried two levels deeper. I have managed that, but the issue here is that now i seem to have almost hardcoded a path to the tag opposed to looping there. How could i change my code to stop me from doing this?

Its from the second foreach where its going wrong imo.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深海少女心 2024-10-13 10:04:07

还没有测试过,但我相信通过使用 xpath 这样的东西会起作用。但是我不确定属性的名称,或者它始终是第一个属性?

public String sqlReading(String fileName, String path, String nodeId)
{
    XmlDocument doc = new XmlDocument();
    doc.Load(fileName);

    XmlNode foundNode = doc.SelectNodes(path).SelectSingleNode("*[@id='" + nodeId + "']/GUIDisplay/sqlSearchString");
    if (foundNode != null)
        return foundNode.InnerText;
    return string.Empty;

}

Haven't tested it but I believe something like this would work, by using a xpath. However I'm not sure the name of the attribute, or is it always the first attribute?

public String sqlReading(String fileName, String path, String nodeId)
{
    XmlDocument doc = new XmlDocument();
    doc.Load(fileName);

    XmlNode foundNode = doc.SelectNodes(path).SelectSingleNode("*[@id='" + nodeId + "']/GUIDisplay/sqlSearchString");
    if (foundNode != null)
        return foundNode.InnerText;
    return string.Empty;

}
真心难拥有 2024-10-13 10:04:07

我不确定这是否完全正确(因为我没有 XML 文档来尝试,但类似的东西应该可以工作

var innerTexts = XDocument.Load(fileName)
    .Elements(path)
    .Where(n => n.Attributes().ElementAt(0).Value == nodeId)
    .SelectMany(n => n.Elements())
    .Where(n => n.Name == "GUIDisplay")
    .SelectMany(n => n.Elements())
    .Where(n => n.Name == "sqlSearchString")
    .Select(n => n.ToString());

Im not sure if this is exaclty right (as I dont have an XML document to try it with, but something similar should work

var innerTexts = XDocument.Load(fileName)
    .Elements(path)
    .Where(n => n.Attributes().ElementAt(0).Value == nodeId)
    .SelectMany(n => n.Elements())
    .Where(n => n.Name == "GUIDisplay")
    .SelectMany(n => n.Elements())
    .Where(n => n.Name == "sqlSearchString")
    .Select(n => n.ToString());
独孤求败 2024-10-13 10:04:07

我想说递归是一个安全的选择(用于迭代嵌套的子节点),但是,根据我收集的信息,结构保持不变。考虑到这一点,为什么不使用 [XmlDocumentObj].SelectSingleNode("/[nodeId='"+nodeId+"']") (或某些传真)呢?它能够按属性名称进行搜索,除非 XML 结构总是更改并且您从没有常量标记(在这种情况下 XPath 可能是一个好主意)。

I would say recursion is a safe bet (for iterating through nested child nodes) Though, from what I gather, the structure remains the same. And with that in mind, why not use [XmlDocumentObj].SelectSingleNode("/[nodeId='"+nodeId+"']") (or some facsimile) instead? This has the ability to search by attribute name, unless the XML structure is always changed and you never have constant tag (in which case XPath is probably a good idea).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文