2014-06-06 135 views
0

我想读取下面的xml中的嵌套元素。到目前为止我已经能够读取chantier/data元素中的数据,但是现在的问题在于如何才能读取<questions><sitePreparation> and <ctm>里面的数据呢? Xml文件和代码已经缩短了一点,因为它们太长了。任何帮助深表感谢。如何读取使用Linq到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); 
     } 
    } 
} 
+0

如何读取数据的工作? –

+0

请仔细阅读这些问题:http://stackoverflow.com/questions/13203975/how-to-parse-deeply-nested-using-linq-to-xml,http://stackoverflow.com/questions/11758904/accessing-嵌套元素通过LINQ到XML ...希望这会有所帮助..干杯! –

+0

看起来不错。那么,阅读“问题”有什么问题?使用相同的方法 –

回答

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元素chantier,而不是chantier元素本身。这就是为什么ch.Element("P1_Question")返回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") 
    }; 

输出:

[ 
    { 
    V2: "V2", 
    V3: "V3", 
    V3_1: "V3_1", 
    V4: "V4", 
    S1_2_2: "S1_2_2", 
    P1_Question: "P1_Q" 
    } 
] 
+0

是否可以读取第一个循环中的元素而不创建第二个元素?我想知道是否可以导航元素,然后导航到正确的元素? –

+1

谢谢谢尔盖,你的例子帮助我理解了Linq如何读取xml。 –

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; 
} 

你有更清洁的代码,也可以用`CHANTIER/data`一个强类型的对象