-1

有没有一种方法可以读取结束标签,例如使用 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   
            }
         }
}

我的 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

4

2 回答 2

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();
    }
}
于 2013-04-15T20:01:04.450 回答
0

与其尝试检测 EndElement 节点,不如简单地反向工作。以您知道自己在哪里的方式存储您的路径信息,然后您可以按从外到内的顺序打印出路径。

我会用 aList<string>或 a来做到这一点StringBuilder, List 会更容易操作。只需在输入新子节点组时存储您希望打印的字符串,并根据需要添加节点名称或属性值,然后编写一个正确解释列表的打印输出函数。

于 2013-04-15T19:54:52.927 回答