2013-10-04 53 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 

編輯來計算所有名的最大名稱長度,在情況下,你有一個更大的文件來運行這個反對,有一些非常長的名字。