2013-04-18 3 views
1

값을 추출해야하는 XDocument로 XML 파일을로드했습니다. 그 파일을 만드는 가장 좋은 방법은 확실치 않습니다. 내가 떠올리는 대부분의 것들은 과잉이거나 XML 규칙을 잘 사용하지 않는 것 같습니다. 나는 XML의 다음 코드가 있습니다XML에서 값 찾기

<entry> 
     <observation classCode="OBS" moodCode="EVN"> 
     <templateId root="2.16.840.1.113883.10.20.6.2.12" /> 
     <code code="121070" codeSystem="1.2.840.10008.2.16.4" codeSystemName="DCM" displayName="Findings"> 
     </code> 
     <value xsi:type="ED"> 
      <reference value="#121071"> 
      </reference> 
     </value> 
     </observation> 
    </entry> 

<entry> 임의의 수의 노드가있을 수 있습니다, 그리고 그들은 모두 비슷한 패턴을 따릅니다. templateId 요소에있는 root 속성 아래의 값은이 항목을 내가 원하는 것으로 식별하는 알려진 UID를 포함합니다. 나는 참고 가치를 얻을 필요가있다.

내 생각은 올바른 templateID 노드를 찾고, 관찰 노드로 돌아가 <valuexsi:type="ED">을 찾은 다음 참조 값을 얻는 것입니다. 이것은 지나치게 복잡하게 보이고, 이것을 할 다른 방법이 있는지 궁금합니다. 내가받은 XML이 종종 XML이 같은 노드 이름 아래에 중첩 한 수

편집 할 수 있습니다. 즉, <observation><observation>이라는 다른 노드 아래에 위치 할 수 있습니다.

+0

샘플 부분에 사용 된 네임 스페이스'xsi '가 있기 때문에 전체 XML 입력을 표시해야하지만 선언 된 방법을 알 수는 없습니다. – MarcinJuraszek

답변

1

문서가 네임 스페이스를 사용하고 쿼리에 누락되어 문제가 발생합니다.

우선 XML의 어딘가에 xsi 네임 스페이스 선언을 찾아야합니다 (맨 위에있는 요소 일 가능성이 높음).

그것은 그 다음과 같이 표시됩니다

xmlns:xsi="http://test.namespace" 

(가), 이름 공간 URI를 가지고 그것을 따라 XNamespace 인스턴스를 생성하는 값이다 :

var xsi = XNamespace.Get("http://test.namespace"); 

그리고 사용 검색 결과 내에서 xsi 변수 :

var query = from o in xdoc.Root.Element("entries").Elements("entry").Elements("observation") 
      let tId = o.Element("templateId") 
      where tId != null && (string)tId.Attribute("root") == "2.16.840.1.113883.10.20.6.2.12" 
      let v = o.Element("value") 
      where v != null && (string)v.Attribute(xsi + "type") != null 
      let r = v.Element("reference") 
      where r != null 
      select (string)r.Attribute("value"); 

var result = query.FirstOrDefault(); 

다음 XML 구조를 테스트했습니다. 재 :

<root xmlns:xsi="http://test.namespace"> 
    <entries> 
    <entry> 
     <observation classCode="OBS" moodCode="EVN"> 
     <templateId root="2.16.840.1.113883.10.20.6.2.12" /> 
     <code code="121070" codeSystem="1.2.840.10008.2.16.4" codeSystemName="DCM" displayName="Findings"> 
     </code> 
     <value xsi:type="ED"> 
      <reference value="#121071"> 
      </reference> 
     </value> 
     </observation> 
    </entry> 
    </entries> 
</root> 

쿼리는 #121071을 반환합니다. 당신의 입력 XML에 대한

당신은 아마 쿼리의 첫 번째 라인을 변경해야합니다 :

from o in xdoc.Root.Element("entries").Elements("entry").Elements("observation") 

당신의 XML 구조에서 <observation> 요소를 일치.

0

다음 도움말의 내용을 따르는 것이 있습니까?

  1. 이 관찰의 templateId 요소는 root가 '당신 속성이있는 유일한 하나 (또는 ​​null)을 찾기 문서
  2. 의 모든 관측 요소를 뽑아 다음과 같이

    XDocument xdoc = GetYourDocumentHere(); 
        var obsvlookfor = 
         xdoc.Root.Descendants("observation") 
          .SingleOrDefault(el => 
           el.Element("templateId") 
            .Attribute("root").Value == "root value to look for"); 
    
        if (obsvlookfor != null) 
        { 
         var reference = obsvlookfor 
          .Element("value") 
          .Element("reference").Attribute("value").Value; 
        } 
    

    내 생각이다 다시 찾고

  3. 해당 관찰 요소를 발견하면 value 요소 아래에있는 reference 요소에 대해 value 특성을 추출하십시오.
+0

응답 해 주셔서 감사합니다. 멋지게 보입니다. 정상적인 상황에서는 이것이 가능했을 것입니다. 그러나, 나는 다시 null을 얻었다. 관측 노드가 또 다른 관측 노드 아래에 중첩되어 있기 때문에 그것이 뿌리 관측을 발견했지만 중첩되지는 않았다고 생각합니다. 나는 이것을 내 질문에 넣었어야했지만 나는 그것을 알아 채지 못했다. – Tim

+0

당신이 제안한 코드로 놀아 보았습니다. 바깥 관측 노드와 일치하도록 값을 변경했을 때도 obsvlookfor에 대해 null을 얻었습니다. – Tim

+0

@Tim 관측치가 XML에 중첩 된 방식은 무엇입니까? 이렇게하면 쿼리 작성 방법에 영향을 미칩니다. 쿼리를 조각으로 나누고 디버거의 각 단계에서 필요한 최적의 쿼리를 결정하는 데 도움이되는 결과를 검토하는 것이 좋습니다. 중첩 된 관측은 쿼리를 관리하기가 다소 까다롭게 만들 수는 있지만 불가능하지는 않습니다. – Clint

0

LINQ에 네임 스페이스를 포함해야 할 수도 있습니다. 당신은 같은 것을 할 것이라는 점을 검색하려면 : 다음

XNamespace ns = xdoc.Root.GetDefaultNamespace(); 

당신의 LINQ에 :

var obsvlookfor = xdoc.Root.Descendants(ns + "observation") 

을 나는이없이 한 번 데이터를 검색하는 몇 가지 문제가 있었다 알고있다. XML 파일이 매우 심도있는 경우 특히 염두에 두어야 할 문제에 대해 말하지 않습니다.