使用c#中的XmlDocument类读取结束标记



是否有一种方法可以读取结束标签,例如使用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这样做,列表更容易操作。只需存储在输入新的子节点组时希望打印的字符串,并根据需要添加节点名称或属性值,然后编写一个打印输出函数来正确地解释列表。

最新更新