2010-12-06 24 views
1

我刚刚编写了一些代码,正如我在编写代码时所想的那样,这将成为搜索特定节点的一种很好的通用方法。当我完成我真正意识到这是一个烂摊子:d如何重写导航节点列表的代码

public String sqlReading(String fileName, String path, String nodeId) 
{ 
    XmlDocument doc = new XmlDocument(); 
    doc.Load(fileName); 

    XmlNodeList names = doc.SelectNodes(path); 
    foreach (XmlNode xmlDocSearchTerm in names) 
    { 
     //if the attribute of the node i start at is the same as where i am now 
     if (xmlDocSearchTerm.Attributes.Item(0).Value.ToString().Equals(nodeId)) 
     { 
      //get a list of all of its child nodes 
      XmlNodeList childNodes = xmlDocSearchTerm.ChildNodes; 

      foreach (XmlNode node in childNodes) 
      { 
       //if there is a node in here called gui display, go inside 
       if (node.Name.Equals("GUIDisplay")) 
       { 
        XmlNodeList list = node.ChildNodes; 
        //find the sqlsearchstring tag inside of here 
        foreach (XmlNode finalNode in list) 
        { 
         if (finalNode.Name.Equals("sqlSearchString")) 
         { 
          return node.InnerText; 
         } 
        } 
       } 
      } 
     } 
    } 
    return ""; 
} 

是我的本意是基于在路径上做的事 - 我将开始检查,看是否该元素有ID我一直在寻找,如果它那么我想进入那里,并没有停下来,直到我得到了深入两层的sqlsearchstring标签。我已经管理了,但这里的问题是,现在我似乎几乎硬编码了一个路径到标签反对循环。我怎么能改变我的代码来阻止我这样做?

它从第二个foreach哪里出错了。

感谢

+0

在XPath,我想你可以替换所有`foreach`与单行循环代码 – 2010-12-06 14:24:48

+2

您是否在寻找XPath?http://support.microsoft.com/kb/308333 – dsolimano 2010-12-06 14:24:50

回答

1

没有测试过,但我相信这样的事情会工作通过使用XPath的,但我不知道属性的名称,或者是它总是第一个属性?

public String sqlReading(String fileName, String path, String nodeId) 
{ 
    XmlDocument doc = new XmlDocument(); 
    doc.Load(fileName); 

    XmlNode foundNode = doc.SelectNodes(path).SelectSingleNode("*[@id='" + nodeId + "']/GUIDisplay/sqlSearchString"); 
    if (foundNode != null) 
     return foundNode.InnerText; 
    return string.Empty; 

} 
0

我想说的递归是一个安全的赌注(通过嵌套子节点迭代)虽然,从我收集,结构保持不变。考虑到这一点,为什么不使用[XmlDocumentObj].SelectSingleNode("/[nodeId='"+nodeId+"']")(或某种传真)呢?这有能力通过属性名进行搜索,除非XML结构总是被更改,并且永远不会有常量标签(在这种情况下,XPath可能是个好主意)。

1

林不知道这是否是正确的exaclty(因为我没有一个XML文档与尝试,但类似的事情应该工作

var innerTexts = XDocument.Load(fileName) 
    .Elements(path) 
    .Where(n => n.Attributes().ElementAt(0).Value == nodeId) 
    .SelectMany(n => n.Elements()) 
    .Where(n => n.Name == "GUIDisplay") 
    .SelectMany(n => n.Elements()) 
    .Where(n => n.Name == "sqlSearchString") 
    .Select(n => n.ToString());