是否有一种方法可以读取结束标签,例如使用XMLDocument类。由于一些限制,我不能使用XmlREader或XmlTextReader。在MSDN中提到我可以使用XmlNodeType。EndElement仅与XMLReader MSDN链接。我的代码是这样的:
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
}
}
}
My XML File"
<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
我不确定你的算法是如何工作的,但我很确定你的方法是错误的。这是提供所描述的路径列表的一种方式:
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();
}
}
不尝试检测EndElement节点,而是简单地反向工作。把你的路径信息存储在这样一种方式中,你知道你在哪里,然后你可以打印出路径从外到内的顺序。
我会用List<string>
或StringBuilder
这样做,列表更容易操作。只需存储在输入新的子节点组时希望打印的字符串,并根据需要添加节点名称或属性值,然后编写一个打印输出函数来正确地解释列表。