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

C# 使用XPath查询从匹配的XML节点获取属性值,c#,xml,extension-methods,xpath,xpathnavigator,C#,Xml,Extension Methods,Xpath,Xpathnavigator,这看起来并不难,但我现在陷入了困境。我试图从匹配给定XPath查询字符串的节点获取特定属性的属性值。以下是我目前掌握的情况: public static IEnumerable<string> GetAttributes(this XmlDocument xml, string xpathQuery, string attributeName) { var doc = new XPathDocument(new XmlNodeReade

这看起来并不难,但我现在陷入了困境。我试图从匹配给定XPath查询字符串的节点获取特定属性的属性值。以下是我目前掌握的情况:

    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;
                    }
                }
            }
        }
    }
公共静态IEnumerable GetAttributes(此XmlDocument xml,
字符串xpathQuery,字符串attributeName)
{
var doc=新的XPathDocument(新的XmlNodeReader(xml));
XPathNavigator nav=doc.CreateNavigator();
XPathExpression expr=nav.Compile(xpathQuery);
XPathNodeIterator迭代器=nav.Select(expr);
while(iterator.MoveNext())
{
XPathNavigator curNav=iterator.Current;
if(curNav.HasAttributes)
{
XmlNode curNode=((IHasXmlNode)curNav.GetNode();
if(null!=curNode)
{
xmldattribute attrib=curNode.Attributes[attributeName];
if(null!=attrib)
{
收益率收益属性值;
}
}
}
}
}
这当前引发一个异常:

System.InvalidCastException:无法将类型为“MS.Internal.Xml.Cache.XPathDocumentNavigator”的对象强制转换为类型为“System.Xml.IHasXmlNode”

我做错了吗?有没有更简单的方法从匹配节点获取属性值?

对于以下xml:

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

如果您使用的是.NET3.5或更高版本,则可以使用LINQtoXML

对于给定的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>
您还可以使用常规XPath语法。在下面的代码中,变量节点保存由“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");

引发异常的初始问题的解决方案

var doc = new XPathDocument(new XmlNodeReader(xml));
应该被…取代

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*);

这不会引发异常,代码也可以正常工作。

为什么不使用LinqToXml?这将大大降低噪音,除非我不知道为什么你不能用Linq?Derp这样做。我看到
SelectNodes
xmlement
上的一个方法,比如
xmlDoc.DocumentElement
,但没有想到检查
XmlDocument
。使用您的示例,但是使用
SelectNodes
对我来说很有用。“您应该完全放弃这个,使用jQuery”您在说什么?这在服务器端或GUI客户端中。您从哪里获取Javascript/jQuery?检查;)
var doc = new XPathDocument(new XmlNodeReader(xml));
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*);