2012-10-25 38 views
0

我的目標是將ValueReference節點,TimeInstant屬性和timePosition節點中包含的數據保存到變量中。我能夠獲得valueReference節點的值(未評論的部分有效),但不能獲得其他兩個值。 任何幫助將不勝感激。使用LINQ從複雜的XML中提取數據

這裏是我的工作代碼:

public void LinqToXml() 
{ 
    XNamespace sosNamespace = XNamespace.Get("http://www.opengis.net/sos/2.0"); 
    XNamespace fesNamespace = XNamespace.Get("http://www.opengis.net/fes/2.0"); 
    XNamespace gmlNamespace = XNamespace.Get("http://www.opengis.net/gml/2.0"); 
    var root = XElement.Load(@"C:\Working Directory\OGCSOS.Service\OGCSOS.Service\Resources\GetObservation_TemporalFilter.xml"); 
    var a = (from level in root.Descendants(sosNamespace + "temporalFilter") 
      select new 
      { 
       valueReference = (string)level.Descendants(fesNamespace + "After") 
               .Elements(fesNamespace + "ValueReference") 
               .First(), 
       /*timeInstant = (string)level.Descendants(fesNamespace + "After") 
               .Elements(gmlNamespace + "TimeInstant") 
               .Attributes(gmlNamespace + "id") 
               .First()*/ 
       /*timePosition = (string)level.Descendants(fesNamespace + "After") 
              .Elements(gmlNamespace + "TimeInstant") 
              .First()*/ 
      }).ToList(); 

這裏是XML我想讀:

<?xml version="1.0" encoding="UTF-8"?> 
<sos:GetObservation xmlns="http://www.opengis.net/sos/2.0" service="SOS" version="2.0.0" 
        xmlns:sos="http://www.opengis.net/sos/2.0" xmlns:fes="http://www.opengis.net/fes/2.0" 
        xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:swe="http://www.opengis.net/swe/2.0" 
        xmlns:swes="http://www.opengis.net/swes/2.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/sos/2.0 
http://schemas.opengis.net/sos/2.0/sos.xsd"> 

    <!--identifier of an offering--> 
    <offering>[email protected]</offering> 

    <!--identifier of an observed property--> 
    <observedProperty>HG</observedProperty> 

    <!--optional temporal filter restricting the results which shall be returned--> 
    <temporalFilter> 
     <fes:After> 
      <fes:ValueReference>phenomenonTime</fes:ValueReference> 
      <gml:TimeInstant gml:id="startPosition"> 
       <gml:timePosition>2008-03-01T17:44:15.000+00:00</gml:timePosition> 
      </gml:TimeInstant> 
     </fes:After> 
    </temporalFilter> 

    <featureOfInterest>DJK001</featureOfInterest> 

</sos:GetObservation> 
+0

此外,如果有人可以建議一個替代可能更容易的本土方法我都聽過。 – Jollyra

+0

可以有多個temporalFilter – Anirudha

+1

好'''''''''''''''XNamespace sosNamespace = XNamespace.Get(「http://www.opengis.net/sos/2.0」);'可以縮寫爲'XNamespace sosNamespace =「http://www.opengis達網絡/ SOS/2.0" ;'。因爲'XNamespace'類背後的想法是通過串聯使用實例來構建'XNames',所以我會使用一個簡短的變量名,例如'XNamespace sos =「http://www.opengis.net/sos/2.0」;',那麼當你調用軸方法時,你有更短的表達式,例如'foo.Elements(sos +「Bar」)'。 –

回答

2

你GML命名空間是不正確的,將其更改爲

XNamespace gmlNamespace = XNamespace.Get("http://www.opengis.net/gml/3.2"); 

可以使用

timeInstant = level.Descendants(fesNamespace + "After") 
        .First() 
        .Element(gmlNamespace + "TimeInstant") 
        .Attribute(gmlNamespace + "id") 
        .Value, 

timePosition = level.Descendants(fesNamespace + "After") 
        .First() 
        .Element(gmlNamespace + "TimeInstant") 
        .Value 
+0

命名空間的好處! – Jollyra

1

你應該做這樣的

XNamespace sosNamespace = "http://www.opengis.net/sos/2.0"; 
XNamespace fesNamespace = "http://www.opengis.net/fes/2.0"; 
XNamespace gmlNamespace = "http://www.opengis.net/gml/3.2"; 
//you had used 2.0 instead of 3.2 
var root = XElement.Load(@"C:\WorkingDirectory\OGCSOS.Service\OGCSOS.Service\Resources\GetObservation_TemporalFilter.xml"); 
var yourList=root.Descendants(sosNamespace+"temporalFilter").Descendants(fesNamespace+"After").Select(x=> 
new 
{ 
ValueReference=x.Element(fesNamespace+"ValueReference").Value, 
timeInstant=x.Element(gmlNamespace+"TimeInstant").Attribute(gmlNamespace+"id").Value, 
timePosition=x.Element(gmlNamespace+"TimeInstant").Element(gmlNamespace+"timePosition").Value 
} 
); 

yourList包含所有數據

0

試試這個代碼之後:

XmlDocument xmlSnippet = new XmlDocument(); 
xmlSnippet.Load(@"C:\Working Directory\OGCSOS.Service\OGCSOS.Service\Resources\GetObservation_TemporalFilter.xml"); 

//Selects all the similar nodes by tag Name....... 
       XmlNodeList xmlSnippetNodes = xmlSnippet.GetElementsByTagName("fes:After"); 

//Checking if any any xmlSnippetNode has matched. 
       if (xmlSnippetNodes != null) 
       { 
        //Checks if the matched xmlSnippetNode that has fes:After attribute is not NULL 


//Stores the value of the matched tag. 
          var valueReference= xmlSnippetNodes.Item(0).Value; 

        var timeInstance=xmlSnippetNodes.Item(1).Attributes["gml:id"].Value; 
       var timePosition =xmlSnippetNodes.Item(1).InnerXml.Name; 


          //Return True if updated correctly. 
          isUpdated = true; 


        } 
1

你也可以使用好老的XPath

var doc = new XPathDocument("1.xml"); 
    var nav = doc.CreateNavigator(); 
    var mng = new XmlNamespaceManager(nav.NameTable); 
    mng.AddNamespace("sos", "http://www.opengis.net/sos/2.0"); 
    mng.AddNamespace("fes", "http://www.opengis.net/fes/2.0"); 
    mng.AddNamespace("gml", "http://www.opengis.net/gml/3.2"); 
    var valueReference = nav.SelectSingleNode("//sos:GetObservation/sos:temporalFilter/fes:After/fes:ValueReference[1]", mng).TypedValue; 
    var TimeInstant = nav.SelectSingleNode("//sos:GetObservation/sos:temporalFilter/fes:After/gml:TimeInstant/@gml:id", mng).TypedValue; 
    var timePosition = nav.SelectSingleNode("//sos:GetObservation/sos:temporalFilter/fes:After/gml:TimeInstant/gml:timePosition[1]", mng).TypedValue; 
+0

我也給過這個鏡頭,但認爲我太深入學習LINQ了。感謝這個好例子。 – Jollyra