2014-02-13 2 views
0

C#을 사용하여 UN 웹 사이트 (http://www.un.org/sc/committees/1267/AQList.xml)에서 XML 파일을 구문 분석하려고합니다.C#에서 UN XML 파일 구문 분석

내가이 파일을 가지고 끊임없이 가지고있는 한 가지 문제가 있습니다. 자식 태그의 수는 <.INDIVIDUAL.> 태그에서 다른 태그로 다양합니다. 한 예는 < .FORTH_NAME.> 하위 태그입니다.

여러 접근법을 시도했지만 어쨌든 항상 같은 문제가 붙어있는 것처럼 보입니다. 다른 수의 자식 태그가 < .INDIVIDUAL.> 태그 안에 있습니다.

내가 달성하고자하는 것은 모든 태그와 그 값을 하나의 <.INDIVIDUAL.> 태그 아래에 수집 한 다음 내 데이터베이스에 원하는 태그 만 삽입하는 것입니다. 태그가 누락 된 경우 (예 : < .FOURTH_NAME.>), 처음 세 개의 이름 만 데이터베이스에 삽입하고 네 번째 이름은 건너 뛰십시오.

  XDocument xdoc = XDocument.Load(path); 

      var tags = (from t in xdoc.Descendants("INDIVIDUALS") 
         from a in t.Elements("INDIVIDUAL") 

         select new 
         { 
          Tag = a.Name, 
          val = a.Value 
         }); 

      foreach (var obj in tags) 
      { 
       Console.WriteLine(obj.Tag + " - " + obj.val + "\t"); 

//insert SQL goes here 
      } 

나 :

여기 LINQ to XML을 사용하여 시도하고 한 몇 가지 예입니다

그러나 이것은 단지 비어 있지 않은 FOURTH_NAME 태그를 수집 ...

  var q = (from c in xdoc.Descendants("INDIVIDUAL") 
        from _1 in c.Elements("FIRST_NAME") 
        from _2 in c.Elements("SECOND_NAME") 
        from _3 in c.Elements("THIRD_NAME") 
        from _4 in c.Elements("FOURTH_NAME") 

        where _1 != null && _2 != null && _3 != null && _4 != null 

        select new 
        { 
         _1 = c.Element("FIRST_NAME").Value, 
         _2 = c.Element("SECOND_NAME").Value, 
         _3 = c.Element("THIRD_NAME").Value, 
         _4 = c.Element("FOURTH_NAME").Value 
        }); 

      foreach (var obj in q) 
      { 
       Console.WriteLine("Person: " + obj._1 + " - " + obj._2 + " - " + obj._3 + " - " + obj._4); 
//insert SQL goes here 
      } 

어떤 아이디어 ??

답변

1

요소에서 값을 호출하는 대신 문자열 캐스트를 사용할 것을 고려하십시오. LINQ to XML은 요소가 없으면 안전하게 null을 반환합니다. 다음을 시도하십시오.

var data = XElement.Load(@"http://www.un.org/sc/committees/1267/AQList.xml"); 
var individuals = data.Descendants("INDIVIDUAL") 
    .Select(i => new { 
     First = (string)i.Element("FIRST_NAME"), 
     Middle = (string)i.Element("SECOND_NAME"), 
     Last = (string)i.Element("THIRD_NAME") 
    }); 

더 유연하고 모든 이름 필드를 얻으려면 다음과 같이하십시오. (I은 추가 숙제 ;-)

data.Descendants("INDIVIDUAL").Elements() 
    .Where (i =>i.Name.LocalName.EndsWith("_NAME")) 
    .Select(i => new { FieldName= i.Name.LocalName, Value=i.Value}); 
+0

이 아주 좋은 도움이됩니다. 이러한 태그를 하드 코딩하지 않고 태그를 동적으로 읽는 방법은 first_name, second 등입니까? – Alex

+1

확실히, 당신은'data.Descendants ("INDIVIDUAL")와 같은 것을 사용하여 이름/값을 얻을 수있다. > new {FieldName = i.Name.LocalName, Value = i.Value}); 그룹화 작업을 추가하거나 개인별로 하위 선택을 할 수도 있습니다. 비즈니스 요구 사항에 따라 파싱을 처리하는 것은 사용자의 몫입니다. 데이터에 정규화가 필요합니다.어떤 경우에는 먼저 분할해야 할 이름이 여러 개인 경우가 있습니다. –

+0

짐 감사합니다, 이것은 내가 필요로하는 전부입니다 ... – Alex

1

가 왜 XmlSerializer 및 LINQ를 대신 사용하지 않는 그룹화 개인의 과정을 떠날거야? 다음과 같이

menu EDIT > Paste Special > Paste XML As Classes.

다음과 같은 데이터를 쉽게 잡아 :

으로는 새로운 CS 파일에 붙여 넣기하여 클래스를 생성, this 대답 설명

var serializer = new XmlSerializer(typeof (CONSOLIDATED_LIST)); 
using (FileStream fileStream = File.OpenRead(@"..\..\aqlist.xml")) 
{ 
    var list = serializer.Deserialize(fileStream) as CONSOLIDATED_LIST; 
    if (list != null) 
    { 
     var enumerable = list.INDIVIDUALS.Select(s => new 
     { 
      FirstName = s.FIRST_NAME, 
      SecondName = s.SECOND_NAME, 
      ThirdName = s.THIRD_NAME, 
      FourthName = s.FOURTH_NAME 
     }); 
    } 
} 

enter image description here

그런 다음 사용자 요구에 더 적합한 술어를 지정할 수 있습니다.

이 경로를가는 것은 엄청난 시간을 절약하고있을 것입니다 적은 오류가 발생하기 쉬운, 필드 등 강력한 타이핑에 액세스 할 문자열을 사용할 필요가 없습니다 ...