2014-04-07 3 views
0

이 같은 많은 질문이 있지만이 것은 매우 독특합니다. 확신 할 수 있습니다! XML 데이터를 두 개의 열 그리드 (Field, Value)로 전개하는 일반적인 솔루션이 필요하지만 실제 도전은 XML 데이터의 계층 구조가 각 응답마다 다릅니다!C#/Linq를 사용하여 XML을 DataGridView로 변환

감사 데이터는 XML 형식으로 데이터베이스에 저장되므로 이러한 응답의 구조는 변경할 수 없지만 가능한 모든 계층 구조를 처리하고 결과를 간단한 눈금으로 사용자에게 표시해야합니다. 당신은 항상 "resultType"와 같은 수준 "가치"가있는 XML에서 볼 수 있듯이

<xml> 
    <results> 
    <resultsDTO> 
     <reportid>173601</reportid> 
     <results> 
     <displayName>Item 1</displayName> 
     <someParameter>blahblah</someParameter> 
     <hidden>false</hidden> 
     <values> 
      <value>10</value> 
      <resultType>PERCENTAGE</resultType> 
     </values> 
     <values> 
      <value>some.pdf</value> 
      <resultType>PDF</resultType> 
     </values> 
     <values> 
      <value>Findings of Item 1</value> 
      <resultType>FINDINGS</resultType> 
     </values> 
     </results> 
     <results> 
     <displayName>Item 2</displayName> 
     <someParameter>blahblah</someParameter> 
     <hidden>false</hidden> 
     <values> 
      <value>20</value> 
      <resultType>PERCENTAGE</resultType> 
     </values> 
     <values> 
      <value/> 
      <resultType>PDF</resultType> 
     </values> 
     <values> 
      <value>Findings of Item 2</value> 
      <resultType>FINDINGS</resultType> 
     </values> 
     </results> 
     <reportTexts> 
     <value/> 
     <resultType>HISTORY</resultType> 
     </reportTexts> 
     <reportTexts> 
     <value>Some info here.</value> 
     <resultType>INFORMATION</resultType> 
     </reportTexts> 
    </resultsDTO> 
    </results> 
</xml> 

는, 그러나 나는 반복하는 방법이 필요합니다 : 여기

는 XML 구조의 샘플입니다 (XML/Results/ResultsDTO/Results/Values ​​/)를 정의하지 않고이 XML을 통해 이러한 결과 유형 및 값을 찾을 수 있으며 데이터와 함께 몇 가지 특수 규칙을 처리 할 수 ​​있습니다.

XDocument doc = XDocument.Load(@"XMLFile1.xml"); 
var query = from c in doc.Descendants("xml").Elements("results").Elements("resultsDTO").Elements("results").Elements("values").Where(n => n.Element("resultType").Value != "PDF") 
      select new 
      { 
       Field = c.Parent.Element("displayName") == null ? c.Element("resultType").Value : c.Parent.Element("displayName").Value + " - " + c.Element("resultType").Value, 
       Value = c.Element("value").Value   
      }; 
dataGridView1.DataSource = query.ToList(); 
:

여기
[Field], [Value] 
Item 1 - Percentage, 10 
Item 1 - Findings, Findings of Item 1 
Item 2 - Percentage, 20 
Item 2 - Findings, Findings of Item 2 
History, NULL 
Information, Some info here. 

내가 달성하기 위해 노력하고있어의 절반을 표시하고 내 현재 코드입니다 :이 같은의 GridView 출력으로이 값을 얻으려고

"PDF"resultType이 표시되지 않도록하고 displayName이 parent에있는 경우 resultType에 추가합니다! 다른 노드에서는 그렇지 않습니다.

현재 XML/Results/ResultsDTO/Results/Values ​​/ 아래의 값만 가져오고 XML/Results/ResultsDTO/ReportTexts의 값은 가져 오지 않습니다.

도움이 될 것입니다. 감사.

답변

1

대부분의 경우에 적합합니다. 당신이 할 필요가있다 : reportTexts 요소의

  1. 연합 (EU)에게 자손뿐만 아니라.
  2. 자손은 경로를 탐색 할 필요가 없습니다. 어떤 출발 경로라도 줄 수 있습니다.

사용하여 다음 쿼리 :

var query = from c in doc.Descendants("values").Union(doc.Descendants("reportTexts")).Where(n => n.Element("resultType").Value != "PDF") 
      select new 
      { 
       Field = c.Parent.Element("displayName") == null ? c.Element("resultType").Value : c.Parent.Element("displayName").Value + " - " + c.Element("resultType").Value, 
       Value = c.Element("value").Value // you can replace "" by null here 
      }; 

출력은 다음과 같다 : 하위 항목의 설명은

[Field], [Value] 
Item 1 - Percentage, 10 
Item 1 - Findings, Findings of Item 1 
Item 2 - Percentage, 20 
Item 2 - Findings, Findings of Item 2 
History, "" 
Information, Some info here. 
+0

덕분에,이 멋지고했다! – bfritz