如何使用Linq to xml读取嵌套元素

时间:2014-06-06 08:02:48

标签: c# xml linq

我正在尝试阅读下面xml中的嵌套元素。到目前为止,我已经能够读取chantier/data元素中的数据,但现在问题在于如何读取<questions><sitePreparation> and <ctm>内的数据? Xml文件和代码已经缩短了一点,因为它们太长了。非常感谢任何帮助。

<?xml version="1.0" encoding="UTF-8"?>
<Audit>
    <controls>
        <guid>
           0001
        </guid>
        <templateVersion>
                    1.0
        </templateVersion>
    </controls>
    <chantier>
        <data>
            <V2>V2</V2>
            <V3>V3</V3>
            <V3_1>V3_1</V3_1>
            <V4>V4</V4>
            <oresTiersPanel>
                <S1_2>S1_2</S1_2>
            </oresTiersPanel>
            <agentsTiersPanel>
                <S1_2_2>S1_2_2</S1_2_2>
            </agentsTiersPanel>
        </data>
        <questions>
            <sitePreparation>
                <P1_Question>P1_Q</P1_Question>
                <P6_Question>P6_Q</P6_Question>
            </sitePreparation>
            <ctm>
                <C1_Question>C1_Q</C1_Question>
                <C2_Question>C2_Q</C2_Question>
                <C2_1>C2_1</C2_1>
            </ctm>
        </questions>
    </chantier>
</Audit>

private static void ReadXml()
{
    XDocument xdoc = XDocument.Load("sipp.xml");

    if (xdoc.Root != null)
    {
        var chantier = from ch in xdoc.Root.Elements("chantier").Elements("data")
                       let agentsTiersPanel = ch.Element("agentsTiersPanel")
                       where agentsTiersPanel != null
                       select new
            {
                v2 = (string)ch.Element("V2"),
                v3 = (string)ch.Element("V3"),
                v3_1 = (string)ch.Element("V3_1"),
                v4 = (string)ch.Element("V4"),
                S1_2_2 = (string)agentsTiersPanel.Element("S1_2_2"),
                S1_2_2_1 = (string)agentsTiersPanel.Element("S1_2_2_1"),
                S1_2_3 = (string)agentsTiersPanel.Element("S1_2_3"),
                S3 = (string)ch.Element("S3"),
               S3_1 = (string)ch.Element("S3_1"),
                P1_Question = (string)ch.Element("P1_Question")
            };

        foreach (var item in chantier)
        {
            Console.WriteLine(item.v2 + " " + item.v3);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

将其反序列化为对象可能更容易。您可以使用VS中的Paste special功能来获取XML结构的类表示。从那里开始,就反序列化而言,它非常简单:

private Audit GetAuditNodes()
{
    Audit audit = null;
    XmlSerializer serializer = new XmlSerializer(typeof(Audit));
    string uri = "data.xml";

    try
    {
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.CheckCharacters = false;
        settings.CloseInput = true;
        settings.DtdProcessing = DtdProcessing.Ignore;
        settings.IgnoreComments = true;
        settings.IgnoreWhitespace = true;

        using (XmlReader reader = XmlReader.Create(uri, settings))
        {
            audit = (Audit)serializer.Deserialize(reader);
        }
    }
    catch (Exception exc)
    {
         //log an error or something
    }

    return audit;
}

您有更清晰的代码,也可以使用强类型对象

答案 1 :(得分:0)

阅读questions元素的示例:

var questions = xdoc.Root.Elements("chantier")
                    .Elements("questions").FirstOrDefault();

if (questions != null)
{
    var sitePreparation = questions.Element("sitePreparation");
    if (sitePreparation != null)
    {
        Console.WriteLine((string)sitePreparation.Element("P1_Question"));
        Console.WriteLine((string)sitePreparation.Element("P6_Question"));
    }
}

如果您希望将P1和P6问题作为匿名对象的一部分返回,请注意,chdata的{​​{1}}元素,而不是chantier元素本身。这就是chantier返回ch.Element("P1_Question")的原因。通过跳过null元素,查询应如下所示:

null

输出:

var chantiers = 
   from chantier in xdoc.Root.Elements("chantier")
   let data = chantier.Element("data")
   let questions = chantier.Element("questions")
   where data != null && questions != null
   select new {
      V2 = (string)data.Element("V2"),
      V3 = (string)data.Element("V3"),
      V3_1 = (string)data.Element("V3_1"),
      V4 = (string)data.Element("V4"),
      S1_2_2 = (string)data.Element("agentsTiersPanel").Element("S1_2_2"),
      P1_Question = (string)questions.Element("sitePreparation")
                                     .Element("P1_Question")
   };