2012-12-08 3 views
4

데이터가 포함 된 태그와 속성의 조합을 사용하는 XML 파일이 있습니다.복잡한 XML 속성 읽기

나는 XML 파일의 구조를 제어 할 수는 없지만 나는 현재 가장이 구조에 접근하는 방법에 대한 의견이있는 경우이를 분석하고 궁금해을 위해 LINQ를보고 기어를 전환하고 있습니다 :

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE call_flow SYSTEM "../../../../dtds/Callflow_1-1.dtd"> 
<call_flow version="1.1" serial="13903" first_element="Element1"> 
    <element_def name="Element1"> 
    <voice class="com.classname.Name"> 
     <static>Element1.xml</static> 
    </voice> 
    <exit_state name="done"> 
     <next_element>Element2</next_element> 
    </exit_state> 
    </element_def> 
    <element_def name="Element2"> 
    <voice class="com.classname.Name2"> 
     <static>Element2.xml</static> 
    </voice> 
    <exit_state name="option1"> 
     <next_element>Element3</next_element> 
    </exit_state> 
    <exit_state name="option2"> 
     <next_element>Element4</next_element> 
    </exit_state> 
    </element_def> 
    <element_def name="Element3"> 
    <voice class="com.classname.Name3"> 
     <static>Element3.xml</static> 
    </voice> 
    <exit_state name="done"> 
     <next_element>Element4</next_element> 
    </exit_state> 
    </element_def> 
    <element_def name="Element4"> 
    <decision> 
     <class src="com.classname.Name4"/> 
    </decision> 
    <exit_state name="0"> 
     <next_element>Element3</next_element> 
    </exit_state> 
    <exit_state name="1"> 
     <next_element>Element5</next_element> 
    </exit_state> 
    </element_def> 
    <element_def name="Element5"> 
    <voice class="com.classname.Name5"> 
     <static>element5.xml</static> 
    </voice> 
    </element_def> 
</call_flow> 

LINQ 코드 샘플을 많이 찾을 수 있지만 Next_Element 및 element_def "name"속성의 값을 모두 얻는 방법을 실제로 볼 수 없습니다.

누군가가 도움을 줄 수 있고 올바른 방향으로 나를 가리킬 수 있다면 감사하게 생각합니다.

+0

'Element4'요소에는 두 개의 next_element 노드가 있습니다. 결과에서 둘 다 원하니? –

답변

0

이것에 대해 무엇 :

var doc = XDocument.Load("myXml.xml"); 
var list = doc.Descendants("element_def") 
       .Select(x => new 
       { 
       elDefName = x.Attribute("name").Value, 
       nextEl = x.Descendants("next_element").Select(y=> y.Value).ToList() 
       }); 

그것은 elDefNameelement_def 노드의 이름 속성의 값이됩니다 및 nextEl이 가능 next_element 값 목록이 포함됩니다 익명 객체의 IEnumerable을 반환합니다 .

+0

화려한 - 나는 이것들을 가지고 나를 두는 곳을 보게 될 것이다. - 내가 처음 보았던 것의 단순함을 정말로 고맙게 생각한다. – Bandolier2k

+0

LINQ를 처음 사용하는 경우 - 중첩 된 foreach 루프보다 결과를 트래버스하는 더 좋은 방법이 있습니까? – Bandolier2k

+0

예, 중첩 루프를 사용할 수 있습니다. 그것은 당신의 유스 케이스가 무엇인지에 달려있다. 예 : XML 구조를 나타내는 일부 객체를 만들려면 괜찮습니다. 그러나 필터링을 원한다면 위에 게시 한 쿼리를 일부 조건과 함께 추가하는 것이 좋습니다. – mipe34

3
XDocument xdoc = XDocument.Load(path_to_xml); 
var query = from ed in xdoc.Descendants("element_def") 
      select new 
      { 
       Name = (string)ed.Attribute("name"), 
       NextElements = ed.Elements("exit_state") 
           .Select(es => (string)es.Element("next_element")) 
      }; 

이 쿼리는 익명 element_def 이름을 포함 Name 속성이됩니다 개체 및 IEnumerable<string>으로 다음 요소 이름의 순서를 반환합니다.

+0

빠른 후속 -이 같은 일을보다 효율적으로 방법이있다 가정하고 LINQ에 새 인 : foreach는 (데이터 var에 p가) { // 출력 요소 이름 Console.WriteLine ("{0}" , p.Name); // 출력에는 next_element 이없는 반환 요소의 다음 요소 // 계정 경우 (p.Name.Contains ("반환")) { //이 더 NextElements 이 없기 때문에 아무 것도 안 함} 다른 을 { foreach (p.NextElements의 문자열 prp) { Console.WriteLine ("\ t \ t {0}", prp.ToString()); } } } – Bandolier2k