我有没有办法阅读结束标签,例如使用XMLDocument类。由于某些限制,我无法使用XmlREader或XmlTextReader。在MSDN中,提到我只能将XmlNodeType.EndElement用于XMLReader MSDN link。我的代码是这样的:
XmlDocument doc = functionWhichReturnsXmlDoc();
XmlNodeList nodes =textDoc.ChildNodes;
foreach (XmlNode node in nodes)
{
switch (node.NodeType)
{
case XmlNodeType.Element:
XmlNodeList nodes =textDoc.ChildNodes;
switch (node.NodeType)
{
case XmlNodeType.Element:
//do something
case XmlNodeType.Text:
//do something
case XmlNodeType.EndElement:
// THIS EVER EXECUTES
}
}
}
我的XML文件“
<Text >
<environment>
<Tempratue>
<element id="COLD">Cold</element>
<element id="MILd">Mild</element>
<element id="HOT">Hot</element>
</Tempratue>
<element id = "Windy">true</element>
</environment>
<dish>
<element id = "dish1">1111</element>
<element id = "dish2">2222</element>
</dish>
</Text>
我想把输出作为字符串列表: -
/Text/Environment/Temprature/COLD
/Text/Environment/Temprature/MILD
/Text/Environment/Temprature/HOT
/Text/Environment/Windy
/Text/dish/dish1
/Text/dish/dish2
提前致谢。
- AAT
答案 0 :(得分:4)
我不确定你是如何设想你的算法工作的,但我很确定你的方法是错误的。这是一种可以提供您所描述的路径列表的方法:
internal static List<string> BuildPaths(XmlDocument doc)
{
List<string> paths = new List<string>();
BuildPaths(doc.DocumentElement, paths);
return paths;
}
private static void BuildPaths(XmlNode node, List<string> paths, string prefix = "/")
{
if (node.Name == "element")
{
// end case - elements named "element"
paths.Add(prefix + node.Attributes["id"].Value);
}
else
{
// iterate through child nodes that are either not named element or that
// have an attribute named "id" (i.e. skip elements named "element" that
// lack an id attribute)
foreach (XmlNode child in node.SelectNodes("*[not(self::element) or @id]"))
{
BuildPaths(child, paths, prefix + node.Name + "/");
}
}
}
在样本XML上运行此操作时,结果是以下字符串的列表:
/Text/environment/Tempratue/COLD
/Text/environment/Tempratue/MILd
/Text/environment/Tempratue/HOT
/Text/environment/Windy
/Text/dish/dish1
/Text/dish/dish2
这是一种我更喜欢的方法,因为它遵循函数式编程原则。在这种情况下,上面的第一个BuildPaths()
方法将是不必要的;您可以将XmlDocument
直接传递给此方法:
private static List<string> BuildPaths(XmlNode node, string prefix = "/")
{
// Get child node if current node is the root
if (node.NodeType == XmlNodeType.Document) { node = node.FirstChild; }
if (node.Name == "element")
{
return new List<string> { prefix + node.Attributes["id"].Value };
}
else
{
return node.SelectNodes("*[not(self::element) or @id]")
.OfType<XmlNode>()
.Select(n => BuildPaths(n, prefix + node.Name + "/"))
.SelectMany(l => l)
.ToList();
}
}
答案 1 :(得分:0)
不是试图检测EndElement节点,而是反向工作。 以您知道自己身份的方式存储您的路径信息,然后您可以按照从外到内的顺序打印出路径。
我会使用List<string>
或StringBuilder
执行此操作,列表会更容易操作。输入新的子节点组时,只需存储要打印的字符串,并根据需要添加节点名称或属性值,然后编写正确解释列表的打印输出函数。