2013-04-11 3 views
6

Мне нужно выбрать все узлы, которые содержат атрибут с определенным именем.выберите все узлы xml, которые содержат определенный атрибут

Это мой текущий, а не рабочий подход.

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

Я стараюсь, чтобы выбрать все узлы, которые содержат атрибут с именем, заданным в параметре метода attributeName и добавить значение переменной list.

Пример:

Этот метод вызова:

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

должен возвращать список, который содержит строку "OnSelectedRelatedContactChanged"

Это файл XML:

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

Далее que stions: Было бы лучше решить это с помощью LINQ?

Решение 1: спасибо, 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; 
} 

Решение 2: спасибо, Джон Скит

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

LINQ к XML Решение выглядит гораздо более элегантно ко мне.

+1

Я бы определенно использовал LINQ для XML для этого. Можете ли вы сделать 'document' вместо' XDocument'? –

+0

Да, я могу, я попробую его с LINQ to XML – Joel

ответ

8

Если вы могли бы использовать LINQ к XML для этого, было бы совершенно тривиальным:

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

XPath вы ищете должны быть

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

Что оригинал XPath делает искал для всех элементов, которые имеют атрибут Name со значением attributeName

Это будет искать любой элемент, который имеет атрибут с attr ibuteName

//*[@title] 

будет возвращать элементы столбцов

+0

Спасибо, за ваше решение он отлично работает. Но мне больше нравится подход LINQ to XML. – Joel

1

Im не уверен в C# синтаксис, но я думаю, что XPath vlaue неправильно. Попробуйте: "// * [@ itemSelectedHandler]". Что должно быть в C#

string xpath = "//*[@" + attributeName + "]"; 
Смежные вопросы