如何在XML结构中导航所有子标签

时间:2014-02-21 12:56:09

标签: c# xml linq xpath

我有以下xml:

   <VON>
        <OverXP name="UML1"  >
            <Property name="actor1" value="1"  />
            <OverXP name="UML2"  >
                <Property name="actor2" value="2"  />      
            </OverXP>  
        </OverXP>
    </VON>

我需要将每个属性都作为树:结果应该如下:

level1:actor1 = 1 level2:actor2 = 2

我的代码:

XPathNavigator nav;
XPathDocument docNav;
XPathNodeIterator NodeIter;
String strExpression;
// Open the XML.
docNav = new XPathDocument(@"C:\uml.xml");
 // Create a navigator to query with XPath.
 nav = docNav.CreateNavigator();
strExpression = "//OverXP//*";
NodeIter = nav.Select(strExpression);

但不起作用!

2 个答案:

答案 0 :(得分:0)

您正在检查@name/string()中属性值的字符串节点,这是不正确的,无法完成。在XPATH中,您不需要像面向对象的代码那样显式地声明类型,只有结果值的类型将在C#层中处理。 string()用于返回所需结果的字符值。

因此,请使用更像//OverXP [@name= 'UML2']

的内容

但是根据您想要的结果,您可能希望使用contains(),如下所示: //OverXP[contains(@name, 'UML')]但这会多次为您提供一些结果,因此您可以将[1]附加到查询中,或者将其细化为更具体的内容。

答案 1 :(得分:0)

这是一个使用 LINQ查询语法的查询,我相信它会得到您想要的结果:

XDocument document = XDocument.Parse(xmlContent);

var query =
    from property in
        document.Descendants("OverXP").Elements("Property")
    select new
    {
        Level = property.Ancestors().Count() - 1,
        Actor = (string)property.Attribute("name"),
        Value = (string)property.Attribute("value")
    };

我已将您的示例数据和此查询合并到演示程序中。请参阅下面的演示程序格式化输出,然后是程序本身。

预期输出

[Level 1] => [actor1 = 1]
[Level 2] => [actor2 = 2]

演示计划

using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

class LinqToXmlDemo
{
    static public void Main(string[] args)
    {
        var xmlContent = GetXml();
        XDocument document = XDocument.Parse(xmlContent);

        var query =
            from property in
                document.Descendants("OverXP").Elements("Property")
            select new
            {
                Level = property.Ancestors().Count() - 1,
                Actor = (string)property.Attribute("name"),
                Value = (string)property.Attribute("value")
            };

        foreach (var item in query)
        {
            Console.WriteLine("[Level {0}] => [{1} = {2}]",
                              item.Level, item.Actor, item.Value);
        }
    }

    static string GetXml()
    {
        return
            @"<VON>
                <OverXP name='UML1'>
                    <Property name='actor1' value='1' />
                    <OverXP name='UML2'>
                        <Property name='actor2' value='2' />
                    </OverXP>
                </OverXP>
              </VON>";
    }
}