简体   繁体   English

使用XPath查询从匹配的XML节点获取属性值

[英]Get attribute values from matching XML nodes using XPath query

This doesn't seem like it should be difficult, but I'm stuck currently. 这似乎不应该是困难的,但我现在卡住了。 I'm trying to get the attribute values for a particular attribute from nodes that match a given XPath query string. 我正在尝试从与给定XPath查询字符串匹配的节点获取特定属性的属性值。 Here's what I have so far: 这是我到目前为止所拥有的:

    public static IEnumerable<string> GetAttributes(this XmlDocument xml,
        string xpathQuery, string attributeName)
    {
        var doc = new XPathDocument(new XmlNodeReader(xml));
        XPathNavigator nav = doc.CreateNavigator();
        XPathExpression expr = nav.Compile(xpathQuery);
        XPathNodeIterator iterator = nav.Select(expr);
        while (iterator.MoveNext())
        {
            XPathNavigator curNav = iterator.Current;
            if (curNav.HasAttributes)
            {
                XmlNode curNode = ((IHasXmlNode)curNav).GetNode();
                if (null != curNode)
                {
                    XmlAttribute attrib = curNode.Attributes[attributeName];
                    if (null != attrib)
                    {
                        yield return attrib.Value;
                    }
                }
            }
        }
    }

This currently throws an exception: 这目前抛出异常:

System.InvalidCastException: Unable to cast object of type 'MS.Internal.Xml.Cache.XPathDocumentNavigator' to type 'System.Xml.IHasXmlNode'. System.InvalidCastException:无法将类型为“MS.Internal.Xml.Cache.XPathDocumentNavigator”的对象强制转换为“System.Xml.IHasXmlNode”。

Am I going about this wrong? 我错了吗? Is there a simpler way to get attribute values from matching nodes? 是否有更简单的方法从匹配节点获取属性值?

For the following xml: 对于以下xml:

<root>
  <elem att='the value' />
</root>

You can get the "the value" text with this C# code 您可以使用此C#代码获取“值”文本

    XmlDocument xdoc = new XmlDocument();
    xdoc.LoadXml(text);
    Console.WriteLine(xdoc.SelectSingleNode("/root/elem/@att").Value);

If you're using .net 3.5 or later you could use linq to Xml 如果你使用.net 3.5或更高版本,你可以使用linq到Xml

For a given xml document 对于给定的xml文档

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <storedProcedures>
    <storedProcedure name="usp_GET_HOME_PAGE_DATA">
      <resultSet name="Features"/>
      <resultSet name="Highlights"/>
    </storedProcedure>
    <storedProcedure name="usp_GET_FEATURES" />
    <storedProcedure name="usp_GET_FEATURE" />
    <storedProcedure name="usp_UPDATE_FEATURE" />
    <storedProcedure name="usp_GET_FEATURE_FOR_DISPLAY">
      <resultSet name="CurrentFeature"/>
      <resultSet name="OtherFeatures"/>
    </storedProcedure>
    <storedProcedure name="usp_GET_HIGHLIGHT_TITLES">
      <resultSet name="Highlights"/>
    </storedProcedure>
  </storedProcedures>
</root>

The following linq expression will get you the values of the "name" attributes of all storedProcedure node 以下linq表达式将为您提供所有storedProcedure节点的“name”属性的值

XDocument xDcoument = XDocument.Load(xmlStoredProcSchemeFile);

  var storedProcedureNames = from doc in xDcoument.Descendants("storedProcedure")
                             select doc.Attribute("name").Value;

you could also use regular XPath syntax. 您还可以使用常规XPath语法。 In the code below the variable node holds the node identified by the "usp_GET_HOME_PAGE_DATA" name and then the attributes variable holds all child nodes (the attributes) of the selected node and it's children. 在下面的代码中,变量节点保存由“usp_GET_HOME_PAGE_DATA”名称标识的节点,然后attributes变量保存所选节点及其子节点的所有子节点(属性)。

  XmlDocument xmlDocument = new XmlDocument();
  xmlDocument.Load(@"C:\inetpub\wwwroot\ASPNETBuilder\BusinessLayer\DataAccessCodeGenerationSchema.xml");
  var node = xmlDocument.DocumentElement.SelectSingleNode("./storedProcedures/storedProcedure[@name='usp_GET_HOME_PAGE_DATA']");
  var attributes = node.SelectNodes("./resultSet/@name");

solution to the initial problem of the exception being thrown... 解决抛出异常的初始问题...

var doc = new XPathDocument(new XmlNodeReader(xml));

should be replaced by... 应该被......取代

var doc = new XmlDocument();
doc.load(*you can either specify the path to the file, the string out of which the xml document is to be generated or specify an xmlreader, look for more overloads*);

This will not throw the exception and the code will work just fine. 这不会抛出异常,代码也可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM