在XML

2013-04-18 43 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">然後得到參考值。這似乎過於複雜,我想知道是否有另一種方式來做到這一點?

EDIT

我接收XML有時可以嵌套在同一節點名下XML。換句話說,<observation>可能位於一個名爲<observation>另一個節點。

+0

你必須顯示你的整個XML輸入,因爲在樣本部分有一個名字空間'xsi',但我們不知道它是如何聲明的。 – MarcinJuraszek

回答

1

您遇到問題,因爲您的文檔使用命名空間,並且您的查詢缺少它們。

首先,你必須要找到(可能是最頂級的元素)xsi命名空間中的XML某處聲明。

它看起來像:

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

將沿東西的下列幫助行?

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; 
    } 

我的想法如下:

  1. 拉出所有的觀測要素的文件
  2. 在查找那裏觀察的templateId元素有一個root屬性你」是唯一一個(或空)重新尋找
  3. 如果您發現該觀察元素,請將value屬性與value元素下的reference元素相拉。
+0

謝謝你的迴應。它看起來很棒,而且我認爲,在正常情況下,這可以做到。但是,我得到了一個空回。我相信這是因爲觀察節點嵌套在另一個觀察節點下,所以它發現了根觀察結果,但沒有發現嵌套結構。我應該把這個放在我的問題中,但我沒有注意到它。 – Tim

+0

我玩了你提供的代碼,發現即使當我改變了值來匹配外部觀察節點,我仍然得到一個null爲obsvlookfor。 – Tim

+0

@Tim如何嵌套在XML中的觀察?因爲這會影響你將如何建立你的查詢。我建議將查詢分解爲碎片並檢查在調試器的每個階段得到的結果,以幫助您確定所需的最佳查詢,嵌套的觀察可能會使查詢在某種程度上更難以管理,但並非不可能。 – Clint

0

您可能需要在您的LINQ的命名空間。若要檢索,你會做這樣的事情:

XNamespace ns = xdoc.Root.GetDefaultNamespace(); 

然後在您的LINQ:

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

我知道我遇到了一些問題,而這一次檢索數據。特別是如果你的XML文件非常深入,不要說它的問題只是要記住的問題。