2013-04-11 39 views
6

Ich muss alle Knoten auswählen, die ein Attribut mit einem bestimmten Namen enthalten.Alle xml-Knoten auswählen, die ein bestimmtes Attribut enthalten

Dies ist mein derzeitiger, nicht funktionierender Ansatz.

public List<string> RetrieveValuesForAttribute(string attributeName) 
{ 
    var list = new List<string>(); 

    string xpath = "//*[@Name='" + attributeName + "']"; 
    XmlNodeList xmlNodeList = document.SelectNodes(xpath); 

    foreach (XmlNode xmlNode in xmlNodeList) 
    { 
     list.Add(xmlNode.Attributes[attributeName].InnerText); 
    } 

    return list; 
} 

Ich versuche, alle Knoten auszuwählen, die das Attribut mit dem Namen in der Methodenparameter attributeName gegeben enthalten und fügen Sie den Wert der Variable list.

Beispiel:

Dieser Methodenaufruf:

List<string> result = RetrieveValuesForAttribute("itemSelectedHandler"); 

Sollte eine Liste zurück, die die Zeichenfolge "OnSelectedRelatedContactChanged"

Dies ist die XML-Datei:

<GroupBoxWrapper id="gbRelatedContacts" text="Related Contacts"> 
    <TabIndex>0</TabIndex> 
    <TabStop>false</TabStop> 
    <PanelWrapper id="pnlRelatedContactsView" width="1350"> 
    <TabIndex>0</TabIndex> 
    <TabStop>false</TabStop> 
    <ListViewWrapper id="lvRelatedContacts" itemSelectedHandler="OnSelectedRelatedContactChanged" itemDoubleClickHandler="OnRelatedContactDoubleClick"> 
     <TabIndex>0</TabIndex> 
     <TabStop>true</TabStop> 
     <ListViewColumns> 
     <Column title="Name" mapNode="Contact\Name" /> 
     <Column title="Lastname" mapNode="Contact\Lastname" /> 
     </ListViewColumns> 
    </ListViewWrapper> 
    </PanelWrapper> 
</GroupBoxWrapper> 

Weitere que stations: Wäre es besser, dies mit LINQ zu lösen?

Lösung 1: danke, YWM

public List<string> RetrieveValuesForAttribute(string attributeName) 
{ 
    var list = new List<string>(); 

    string xpath = @"//*[@" + attributeName + "]"; 
    XmlNodeList xmlNodeList = document.SelectNodes(xpath); 

    foreach (XmlNode xmlNode in xmlNodeList) 
    { 
     list.Add(xmlNode.Attributes[attributeName].InnerText); 
    } 

    return list; 
} 

Lösung 2: danke, Jon Skeet

public List<string> RetrieveValuesForAttribute(string attributeName) 
{ 
    //document is an XDocument 
    return document.Descendants() 
        .Attributes(attributeName) 
        .Select(x => x.Value) 
        .ToList(); 
} 

Die LINQ to XML-Lösung für mich weit mehr elegant aussieht.

+1

Ich würde definitiv LINQ zu XML dafür verwenden. Kann man "Dokument" stattdessen ein "XDocument" machen? –

+0

Ja, ich kann, ich werde es mit LINQ to XML versuchen – Joel

Antwort

8

Wenn Sie LINQ to XML für diese verwenden könnte, wäre es ganz trivial:

// Note that there's an implicit conversion from string to XName, 
// but this would let you specify a namespaced version if you want. 
public List<string> RetrieveValuesForAttribute(XName attributeName) 
{ 
    // Assume document is an XDocument 
    return document.Descendants() 
        .Attributes(attributeName) 
        .Select(x => x.Value) 
        .ToList(); 
} 
4

Die XPath Sie suchen, sollten

"//*[@" + attributeName + "]" 

sein Was Ihre ursprüngliche XPath wurde tat suchen für alle Elemente, die ein Name Attribut mit dem Wert haben attributeName

Dies wird nach einem Element suchen, das ein Attribut mit attr hat

ibuteName
//*[@title] 

zurückkehren würde die Säulenelemente

+0

Vielen Dank, für Ihre Lösung funktioniert es gut. Aber ich mag den Ansatz LINQ to XML mehr. – Joel

1

Ich bin nicht sicher über die C# Syntax, aber ich denke, die XPath vlaue falsch ist. Bitte versuchen Sie: "// * [@ itemSelectedHandler]". Was sollte in C#

string xpath = "//*[@" + attributeName + "]"; 
Verwandte Themen