使用Linq读取XML而不使用元素名称

时间:2013-10-04 14:54:38

标签: c# xml linq

我需要读取一个XML文件,我正在尝试使用Linq,但是我遇到了一些问题。我需要能够在不知道元素名称的情况下获得desendants。这可能吗?

这是XML:

<Root>
        <myResponse>
            <GUID></GUID>
            <TType code="1">myTType Value
                <TSubType tc="1">TSubType Value</TSubType>
            </TType>    
            <TDate>1999-09-19</TDate>
            <TTime>16:00:00.0Z</TTime>
        </myResponse>
    </Root> 

这是我的代码:

using (XmlReader nodeReader = XmlReader.Create(@"C:\Projects\GetXML\Test2.xml"))

                 {
                     nodeReader.MoveToContent();

                XDocument xRoot = XDocument.Load(nodeReader, LoadOptions.SetLineInfo);


            foreach (XElement e in xRoot.Elements("Root").DescendantsAndSelf())
                Console.WriteLine("{0}{1}{2}",
                    ("".PadRight(e.Ancestors().Count() * 2) + e.Name).PadRight(20), " = " ,
                    (e.Value).PadRight(5));


                }

我的结果:

Root                 = 


        myTType Value
            TSubType Value

        1999-09-19
        16:00:00.0Z


  myResponse         = 

        myTType Value
            TSubType Value

        1999-09-19
        16:00:00.0Z

    GUID             =      
    TType            = myTType Value
            TSubType Value

      TSubType       = TSubType Value
    TDate            = 1999-09-19
    TTime            = 16:00:00.0Z

我期待的是:

Root                 = 
        myResponse         = 

                GUID             =      
                TType            = myTType Value    
                  TSubType       = TSubType Value
                TDate            = 1999-09-19
                TTime            = 16:00:00.0Z        

2 个答案:

答案 0 :(得分:0)

请尝试使用:

,而不是使用e.Value

string.Concat(e.Nodes().OfType<XText>().Select(t => t.Value))

你也可以使用:

e.Nodes().OfType<XText>().FirstOrDefault().Value

然后你冒险得不到所有的文本(如果它被拆分)。例如:

<Root>
  <myResponse>
            <GUID></GUID>
            <TType code="1">myTType Value
                <TSubType tc="1">TSubType Value</TSubType>
               Some more text
            </TType>    
            <TDate>1999-09-19</TDate>
            <TTime>16:00:00.0Z</TTime>
        </myResponse>
    </Root> 

使用这个XML,第一段代码还将包含“更多文本”,而第二段则不包括。

答案 1 :(得分:0)

以下是我为使格式化结果与您期望的结果相似所做的工作。

XElement root = XElement.Load("xmlfile1.xml");
var allNodes = root.DescendantNodesAndSelf();
int maxNameLength = allNodes.OfType<XElement>()
    .Select(x => x.Name.LocalName.Length)
    .Max();
foreach (XNode x in allNodes)
{
    XElement node = x as XElement;
    if (node != null)
    {
        int numAncestors = node.Ancestors().Count();

        XText textNode = node.Nodes().OfType<XText>().FirstOrDefault();
        string text = "";
        if (textNode != null)
            text = textNode.Value.Trim();

        string name = node.Name.LocalName;
        // PadLeft() subtracts the string.Length from the padding
        // so add its length to the padding amount
        string left = name.PadLeft(numAncestors * 5 + name.Length);
        // PadRight() wasn't giving the expected results 
        // so improvised with the following
        string right = left + "".PadLeft(maxNameLength + 5 - name.Length);

        Console.WriteLine("{0} = {1}", right, text);
    }
}

结果:

Root            = 
     myResponse      = 
          GUID            = 
          TType           = myTType Value
               TSubType        = TSubType Value
          TDate           = 1999-09-19
          TTime           = 16:00:00.0Z

编辑计算所有名称的最大名称长度,如果你有一个更大的文件来运行它,并且有一些非常长的名字。