2015-07-09 2 views
0

У меня есть необработанный XML-файл, который создается из отчета. Формат XML чрезвычайно запутан. Цель того, что я пытаюсь сделать, это пройти через этот XML и получить значение ObjectName и FormattedValue внутри каждого узла <FormattedAreaPair Level="2" Type="Details">:C# Read XML Multiple Nested

<FormattedReport xmlns="urn:crystal-reports:schemas" 
       xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"> 
    <FormattedAreaPair Level="0" Type="Report"> 
    <FormattedAreaPair Level="1" Type="Group"> 
     <FormattedAreaPair Level="2" Type="Details"> 
     <FormattedArea Type="Details"> 
      <FormattedSections> 
      <FormattedSection SectionNumber="0"> 
       <FormattedReportObjects> 
       <FormattedReportObject xsi:type="CTFormattedField" 
             Type="xsd:string" 
             FieldName="{ado.agent_extension}"> 
        <ObjectName>Field2</ObjectName> 
        <FormattedValue>3531</FormattedValue> 
        <Value>3531</Value> 
       </FormattedReportObject> 
       <FormattedReportObject xsi:type="CTFormattedField" 
             Type="xsd:string" 
             FieldName="{ado.agent_state}"> 
        <ObjectName>Field4</ObjectName> 
        <FormattedValue>Logged-in</FormattedValue> 
        <Value>Logged-in</Value> 
       </FormattedReportObject> 
       <FormattedReportObject xsi:type="CTFormattedField" 
             Type="xsd:short" 
             FieldName="{ado.reason_code}"> 
        <ObjectName>Field5</ObjectName> 
        <FormattedValue>0</FormattedValue> 
        <Value>0.00</Value> 
       </FormattedReportObject> 
       <FormattedReportObject xsi:type="CTFormattedField" 
             Type="xsd:string" 
             FieldName="{@tf_duration}"> 
        <ObjectName>Field7</ObjectName> 
        <FormattedValue>0:00:00</FormattedValue> 
        <Value>0:00:00</Value> 
       </FormattedReportObject> 
       <FormattedReportObject xsi:type="CTFormattedField" 
             Type="xsd:string" 
             FieldName="{@tf_Agent_ID}"> 
        <ObjectName>TemplateField11</ObjectName> 
        <FormattedValue>Users_Name</FormattedValue> 
        <Value>Users_Name</Value> 
       </FormattedReportObject> 
       <FormattedReportObject xsi:type="CTFormattedField" 
             Type="xsd:timeInstant" 
             FieldName="{@tf_Transition_Time}"> 
        <ObjectName>TemplateField21</ObjectName> 
        <FormattedValue>6/1/2015 6:43:31AM</FormattedValue> 
        <Value>2015-06-01T06:43:31</Value> 
       </FormattedReportObject> 
       </FormattedReportObjects> 
      </FormattedSection> 
      </FormattedSections> 
     </FormattedArea> 
     </FormattedAreaPair> 

Я попытался несколько различных способов (я совсем нуб для чтения XML).

с помощью System.XML: - Нет данных

XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.Load(@"C:\TEST\Reports\Test.xml"); 
XmlNode node = xmlDoc.DocumentElement.FirstChild; 
XmlNodeList lstFields = node.ChildNodes; 

for(int i = 0; i <lstFields.Count; i++) 
{ 
    //look for Node 
    if (lstFields[i].Name == "FormattedSections") 
    { 
     XmlNodeList lstCrap = lstFields[i].ChildNodes; 
     for (int j = 0; j < lstCrap.Count; j++) 
     { 
      txtTest.Text += lstCrap[j].InnerText + "\n"; 
     } 
    } 
} 

использованием System.Xml.Linq:

private string pullValue (string productID) 
    { 
     XDocument xdoc = XDocument.Load(@"C:\TEST\Reports\Test.xml"); 
     var detailsTest = xdoc 
      .Descendants("FormattedReportObjects") 
      .Where(extension => extension.Descendants("FormattedReportObject") 
      .Any(number => (string)number.Attribute("Value") 
      == productID)).FirstOrDefault(); 
     return (string)detailsTest; 
    } 
+0

Прочитайте это: https://msdn.microsoft.com/en-us/library/cc189056(v=vs.95).aspx –

+0

Могли бы вы после того, что ваш пытался до сих пор? –

+0

Вне XML-файла ваш первый и второй примеры выглядят несвязанными, и ваш второй пример не имеет никакого отношения к LINQ to XML .... – Tim

ответ

1

Что проблема? Это просто!

XElement report = XElement.Load("file.xml"); 

XNamespace ns = "urn:crystal-reports:schemas"; 

var formattedAreaPair = report 
    .Descendants(ns + "FormattedAreaPair") 
    .Where(elem => elem.Attribute("Level").Value == "2" && elem.Attribute("Type").Value == "Details") 
    .First(); 

foreach (var elem in formattedAreaPair.Descendants(ns + "FormattedReportObject")) 
{ 
    Console.WriteLine(elem.Element(ns + "ObjectName").Value); 
    Console.WriteLine(elem.Element(ns + "FormattedValue").Value); 
    Console.WriteLine(); 
} 
+0

очень мило, спасибо – user3930238