在C#中查找所有特定值的子节点

Posted

技术标签:

【中文标题】在C#中查找所有特定值的子节点【英文标题】:Find all the child node of specific value in C# 【发布时间】:2012-09-30 12:17:28 【问题描述】:
<main>
  <myself>
    <pid>1</pid>
    <name>abc</name>
  </myself>
  <myself>
    <pid>2</pid>
    <name>efg</name>
  </myself>
</main>

那是我的名为 simpan 的 XML 文件。我有两个按钮。下一个和上一个。我想要做的是,当用户单击按钮时,所有信息都将显示在 TextBox 上。搜索节点将基于 pid。

下一步按钮将添加 1 个 pid 值(假设 pid=2),它将搜索具有相同 pid=2 值的节点。它还将显示 pid=2 的名称。 (显示名称=abc)

同样转到上一个按钮,它将减少 1 个 pid 值 (pid=1)。

有人知道怎么做吗?

//------------编辑-------

感谢 L.B,我正在尝试使用他的代码。但是我遇到了错误。

我的代码实现是否正确?

private void previousList_Click(object sender, EventArgs e)
    
        pid = 14;

        XDocument xDoc = XDocument.Parse("C:\\Users\\HDAdmin\\Documents\\Fatty\\SliceEngine\\SliceEngine\\bin\\Debug\\simpan.xml");

        var name = xDoc.Descendants("myself")
                    .First(m => (int)m.Element("PatientID") == pid)
                    .Value;

        textETA.Text = name;
        ////////////////////


    

【问题讨论】:

将插入符号放在XDocument.Parse 上并按F1,然后阅读文档,尤其是参数说明。 使用 XML 字符串调用 XDocument.Parse(),使用带有文件名的 XDocument.Load()。 【参考方案1】:
int pid = 2;
XDocument xDoc = XDocument.Parse(xml); //Load

var name = xDoc.Descendants("myself")
            .First(m => (int)m.Element("pid") == pid)
            .Element("name")
            .Value;

【讨论】:

我遇到了一个错误。见我的帖子。我与错误一起发布 @Sarabrown 从文件加载使用 xdocument 的加载方法。另请参阅编辑后的答案【参考方案2】:

您可以使用以下XPath 列出所有Myself 标签,然后使用简单的Linq 命令查找您想要的内容:

XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "file1.xml");
        var resNodes = xmlDoc.SelectNodes("//myself");
        XmlNode res = null;
        var val = textBox1.Text;

        var item = from XmlNode x in resNodes
                   select x;

        foreach (var nodP in item) 
            foreach (XmlNode nod in nodP.ChildNodes) 
                if (nod.InnerText == val) 
                    res = nodP;
                
            
        

        if (res == null)
            // not found!
            ;
        else
            // show the result
            ;

【讨论】:

【参考方案3】:

叫我老式的,但你可以使用XPath,例如:

string xml =
    @"<main>
        <myself>
            <pid>1</pid>
            <name>abc</name>
        </myself>
        <myself>
            <pid>2</pid>
            <name>efg</name>
        </myself>
      </main>";

using System.Xml;

....

XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
// Replace "2" in the string below with the desired pid
XmlNode xmlNode = 
    xmlDocument.DocumentElement.SelectSingleNode("myself/name[../pid=2]");
// xmlNode contains the <name>efg</name> XmlElement. For example:
string name = xmlNode.Value;

如果它可以匹配多个节点,例如可能有多个 &lt;myself&gt; 元素且子元素 &lt;pid&gt; 设置为 2,请改用以下内容:

foreach(XmlNode xmlNode in 
    xmlDocument.DocumentElement.SelectNodes("myself/name[../pid=2]"))

    // xmlNode contains the matching <name> element

在这两种情况下,都可以使用Value 属性从XmlNode 中提取值。

【讨论】:

请问我应该在foreach(xmlNode中的XmlNode xn)中放入什么?如果我想在 textName.Text 中出现 xmlNode?​​span> 如果它可以匹配多个元素,我在答案中添加了另一个案例。 我假设我应该把它放在 foreach >> textETA.Text = xmlNode;但它说无法将 system.xml.xmlnode 转换为字符串。 使用 XmlNode 的 Value 属性。有关 XmlNode 的帮助,请参阅 msdn.microsoft.com/en-us/library/system.xml.xmlnode.aspx。【参考方案4】:
public class simpman


    private static XElement root = XElement.Load("Simpman.xml");

    public static string GetItem(int index)
    
        XElement item =
        (from element in root.Elements("myself")
        where (int)element.Element("pid") == index
        select element.Element("name")).SingleOrDefault();

        return item != null ? item.Value : "Please check the Index";
    

将静态 itemIndex 初始化为 1 并进一步使用它,例如 itemIndex++(用于 Next)和 itemIndex--(用于 Prev)。

【讨论】:

【参考方案5】:
private void previousList_Click(object sender, EventArgs e)

    pid = 14;

    XDocument xDoc = XDocument.Load(@"C:\Users\HDAdmin\Documents\Fatty\SliceEngine\SliceEngine\bin\Debug\simpan.xml");

    var name = xDoc.Root
                   .Descendants("myself")
                   .FirstOrDefault(e => e.Element("pid")
                   .Value
                   .Equals(pid.ToString(CultureInfo.InvariantCulture)))
                   .Element("name")
                   .Value;

    textETA.Text = name;

【讨论】:

这不是我的原始代码吗?这正是问题所在? 你使用XDocument.Parse() 并解析文件路径,这就是你得到那个错误的原因。要从文件 U 中获取 xDoc,应使用 XDocument.Load()。我没有检查查询的实现,我只是解释了为什么你会收到 U 要求的错误。 我明白了..谢谢。我没有首先注意到它。但再次感谢您的解释。 @sarabrown,查看我的更新,我建议我修复了您的姓名查询。好吧,至少,它在 .Net 4.5 上对我来说很好。 我用的是microsoft visual studio 2010。为什么说CultureInfo不存在?【参考方案6】:

XmlDocument doc = new XmlDocument(); FileStream fs = new FileStream(rootXMLPath, FileMode.Open, FileAccess.Read); doc.Load(fs); XmlNode node = doc.DocumentElement;

nodeName = "/main/myself";

var child1 = node.SelectSingleNode(nodeName).ChildNodes[0].FirstChild.InnerXml; var child2 = node.SelectSingleNode(nodeName).ChildNodes[0].LastChild.InnerXml; var child3 = node.SelectSingleNode(nodeName).ChildNodes[1].FirstChild.InnerXml; var child4 = node.SelectSingleNode(nodeName).ChildNodes[1].LastChild.InnerXml;

【讨论】:

以上是关于在C#中查找所有特定值的子节点的主要内容,如果未能解决你的问题,请参考以下文章

使用 linq 和 c# 的最大父 ID 的子节点数

xpath按元素和属性查找节点,其中包含具有特定id的子元素

高手帮忙:sql 里怎样递归判断父节点和子节

TreeView 点击触发父节点子节点的连锁反应选中与取消

C# - 查找树视图控件的特定节点或子节点

给元素添加子节点,元素子节点数改变,反过来影响上方调用其值的异步任务回调函数(如click。load,定时器等