我刚刚写了一些代码,正如我写的那样,我认为这将是一个很好的搜索特定节点的通用方法。当我完成后,我实际上意识到这是一团糟: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标签被深埋两层。我已经设法了,但问题是,现在我似乎已经几乎硬编码了一个反向循环的标记路径。我怎么能改变我的代码来阻止我这样做呢?
它来自第二个出错的地方。
由于
答案 0 :(得分:1)
我不确定这是否完全正确(因为我没有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());
答案 1 :(得分: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;
}
答案 2 :(得分:0)
我会说递归是一个安全的赌注(用于迭代嵌套的子节点)虽然,从我收集的结构来看,结构保持不变。考虑到这一点,为什么不使用[XmlDocumentObj].SelectSingleNode("/[nodeId='"+nodeId+"']")
(或一些传真)呢?这可以按属性名进行搜索,除非XML结构总是被更改,并且你永远不会有常量标记(在这种情况下,XPath可能是一个好主意)。