2013-10-04 125 views
2

我需要读取一个XML文件,我正在尝试使用Linq,但是我有一些问题要到达后代。我需要能够在不知道元素名称的情况下获取相关的副产品。这可能吗?使用没有元素名称的Linq读取XML

这里是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   
+0

标题和说明与您的实际/预期节目有很大不同。你*是*在事先不知道他们的名字的情况下获取元素,你只是没有获得空元素,正确地格式化结果等。 –

+0

作为一个方面说明,这可能是我见过的最差的缩进代码。 – recursive

回答

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代码的第一片还将包括“一些更多的文本”,并且第二片不会。

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 

编辑来计算所有名的最大名称长度,在情况下,你有一个更大的文件来运行这个反对,有一些非常长的名字。