2010-11-29 10 views
11

Dies scheint nicht wie es schwierig sein sollte, aber ich bin derzeit stecken. Ich versuche, die Attributwerte für ein bestimmtes Attribut von Knoten zu erhalten, die mit einer bestimmten XPath-Abfragezeichenfolge übereinstimmen. Hier ist, was ich bisher:Erhalten Sie Attributwerte von übereinstimmenden XML-Knoten mit XPath-Abfrage

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; 
        } 
       } 
      } 
     } 
    } 

Das derzeit eine Ausnahme auslöst:

System.InvalidCastException: Kann nicht das Objekt des Typs ‚MS.Internal.Xml.Cache.XPathDocumentNavigator‘ werfen 'eingeben System.Xml.IHasXmlNode '.

Gehe ich falsch? Gibt es eine einfachere Möglichkeit, Attributwerte von übereinstimmenden Knoten zu erhalten?

+1

Warum nicht LinqToXml verwenden? Dies würde den Lärm beträchtlich reduzieren, wenn ich nicht einen Grund vermisse, warum du das nicht mit Linq machen kannst? –

Antwort

31

Für die folgende xml:

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

Sie können die "den Wert" Text mit diesem C# -Code zu bekommen

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

Derp. Ich hatte 'SelectNodes' gesehen, war eine Methode auf einem' XmlElement', wie 'xmlDoc.DocumentElement', dachte aber nicht,' XmlDocument' zu prüfen. Die Verwendung Ihres Beispiels, aber mit 'SelectNodes' funktioniert für mich. –

+0

+1 Gute Antwort. –

4

Wenn Sie mit .net 3.5 oder höher können Sie Linq verwenden in XML

Für ein bestimmtes XML-Dokument

<?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> 

Die folgende Linq Ausdruck finden Sie die Werte des „name“ erhalten Attribute aller StoredProcedure Knoten

XDocument xDcoument = XDocument.Load(xmlStoredProcSchemeFile); 

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

Sie auch regelmäßige XPath-Syntax verwenden könnte. Im folgenden Code enthält der variable Knoten den Knoten, der durch den Namen "usp_GET_HOME_PAGE_DATA" identifiziert wird, und die Attributvariable enthält dann alle untergeordneten Knoten (die Attribute) des ausgewählten Knotens und seine untergeordneten Elemente.

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"); 
+4

"Sie sollten das vollständig fallen lassen und jQuery verwenden" –

+0

Wovon redest du? Dies ist auf der Serverseite oder in einem GUI-Client. Woher bekommst du Javascript/jQuery? –

+2

Überprüfen Sie http://meta.stackexchange.com/questions/19478/the-many-memes-of-meta/19492#19492 **;) ** –

1

Lösung für das Ausgangsproblem der Ausnahme geworfen ...

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

sollte ...

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

Dies wird nicht die Ausnahme auslösen und den Code ersetzt werden wird gut funktionieren.