2

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

这是 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        
4

2 回答 2

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

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

于 2013-10-05T17:03:11.380 回答
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,第一段代码也将包含“一些更多的文本”,而第二段则不会。

于 2013-10-04T15:06:54.703 回答