如何从元素中具有相同名称的 xml 文件中获取特定值?

Posted

技术标签:

【中文标题】如何从元素中具有相同名称的 xml 文件中获取特定值?【英文标题】:How to get specific Values from a xml file with same Name in a element? 【发布时间】:2013-09-12 06:12:44 【问题描述】:

我不知道如何从这个特定的 XML 文档中提取值,并且正在寻求一些帮助,因为我对 xml 解析不是很有经验。

我必须使用XDocument.Load 来加载文件。

其实我在用

doc = XDocument.Load(uri);
challenge = GetValue(doc, "Challenge");

这没有任何问题,但是如何获得元素权利的内在价值? (多个“名称”) 在一天结束时,我需要现在

Phone = x
Dial = x
HomeAuto = x
BoxAdmin = x

也可能缺少某些条目(电话、拨号、HomeAuto、BoxAdmin)。这 是动态的。

这是我的 xml 文件:

<SessionInfo>
 <SID>68eba0c8cef752a7</SID>
 <Challenge>37a5fe9f</Challenge>
 <BlockTime>0</BlockTime>
 <Rights>
  <Name>Phone</Name>
  <Access>2</Access>
  <Name>Dial</Name>
  <Access>2</Access>
  <Name>HomeAuto</Name>
  <Access>2</Access>
  <Name>BoxAdmin</Name>
  <Access>2</Access>
 </Rights>
</SessionInfo>

编辑:(添加 GetValue 方法)

public string GetValue(XDocument doc, string name)
 
   XElement info = doc.FirstNode as XElement;
   return info.Element(name).Value;
 

【问题讨论】:

嘿 @DanB - 对您的 XML 进行旁注 - 您最好将相关的名称和访问标签包装在父元素中,或者使用一个带有 NameAccess 属性的 Right 元素.这清楚地表明两者之间存在关系,并且应该使事情更容易处理。对即将到来的实际问题的回答。 . . 发布GetValue 的代码也会有所帮助。 @JohnLBevan - 你完全正确,不幸的是,这个 xml 来自第 3 方的网络设备,我无法更改布局。 @Tim Ups,我用 GetValue 方法更新问题 XPath 的典型工作。 【参考方案1】:

注意:此解决方案使用扩展方法,因此 using 指令很重要,否则您将看不到所需的功能。

using System;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Collections.Generic;

namespace ***

    class Program
    
        const string xml = "<SessionInfo><SID>68eba0c8cef752a7</SID><Challenge>37a5fe9f</Challenge><BlockTime>0</BlockTime><Rights><Name>Phone</Name><Access>2</Access><Name>Dial</Name><Access>2</Access><Name>HomeAuto</Name><Access>2</Access><Name>BoxAdmin</Name><Access>2</Access></Rights></SessionInfo>";
        static void Main(string[] args)
        

            XDocument doc = XDocument.Parse(xml); //loads xml from string above rather than file - just to make it easy for me to knock up this sample for you
            string nameOfElementToFind = "Name";
            IEnumerable<XElement> matches = doc.XPathSelectElements(string.Format("//*[local-name()='0']",nameOfElementToFind));
            //at this stage you can reference any value from Matches by Index
            Console.WriteLine(matches.Count() > 2 ? "Third name is: " + matches.ElementAt(2).Value : "There less than 3 values");
            //or can loop through
            foreach (XElement match in matches)
            
                Console.WriteLine(match.Value);
                //or if you also wanted the related access info (this is a bit loose / assumes the Name will always be followed by the related Value
                //Console.WriteLine("0: 1", match.Value, match.XPathSelectElement("./following-sibling::*[1]").Value);
            
            Console.WriteLine("Done");
            Console.ReadKey();
        
    

这里的重要一点是IEnumerable&lt;XElement&gt; matches = doc.XPathSelectElements(string.Format("//*[local-name()=\'0\']",nameOfElementToFind)); 行。在string.format 发生之后,XPath 是//*[local-name()='Name']。此 XPath 语句表示查找名称为 Name 的所有节点。 local-name() 函数在那里是因为我们还没有说明正在使用什么架构,在这种情况下,我们想要任何名为 Name 的元素,而不考虑架构。

XmlNamespaceManager nm = new XmlNamespaceManager(new NameTable());
nm.AddNamespace("eg", "http://Example/Namespace/Replace/With/Your/Docs/Namespace");
IEnumerable<XElement> matches = document.XPathSelectElements("//eg:Name", nm);

双正斜杠表示搜索文档中的任何位置。要将其限制为权利,您可以说/eg:SessionInfo/eg:Rights/eg:Name。如果您不熟悉它,如果您想充分利用 XML 文档,XPath 是一种很棒的语言/必不可少的语言。如果您对此有任何疑问,请给我们留言,或在线浏览;那里有很棒的教程。

【讨论】:

小建议:“使用语句”应该是“使用指令”; “using 语句”是 using 块,如 using (SqlConnection conn = new SqlConnection()),而“using 指令”用于允许在命名空间中使用类型或为命名空间创建别名。 感谢@Tim - 已更新。遗憾的是,我对术语不太感兴趣。 这看起来很有希望,我将在今天实施并报告。非常感谢您的帮助,这为我节省了很多时间。太好了!

以上是关于如何从元素中具有相同名称的 xml 文件中获取特定值?的主要内容,如果未能解决你的问题,请参考以下文章

使用 SAX 解析器,如何解析具有相同名称标签但元素不同的 xml 文件?

如何从结构类似于Java的XML文件中获取特定元素

如何获取具有相同名称的元素并根据 XSLT 中的子节点值对它们进行排序

C#如何从xml文件中获取所有元素名称

如何使用jQuery在某些特定div中选择具有相同名称的所有元素[重复]

SimpleXML:选择具有特定属性值的元素