7

我必须选择包含具有特定名称的属性的所有节点。

这是我目前的,不工作的方法。

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>

进一步的问题:用 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:谢谢 Jon Skeet

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

LINQ to XML 解决方案在我看来要优雅得多。

4

3 回答 3

9

如果您可以为此使用 LINQ to 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();
} 
于 2013-04-11T09:58:19.113 回答
5

您正在寻找的 XPath 应该是

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

您最初的 XPath 所做的是寻找所有Name具有该值的属性的元素attributeName

这将查找具有attributeName 属性的任何元素

//*[@title]

将返回列元素

于 2013-04-11T09:58:26.523 回答
2

我不确定 C# 语法,但我认为 xpath vlaue 是错误的。请尝试:“//*[@itemSelectedHandler]”。在c#中应该做什么

  string xpath = "//*[@" + attributeName + "]";
于 2013-04-11T10:07:57.893 回答