2012-11-02 30 views
0

我有下面的XML:的LINQ to 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>2010-07-31T01:05:00</gml:timePosition> 
      </gml:TimeInstant> 
     </fes:After> 
    </temporalFilter> 

    <featureOfInterest>DJK001</featureOfInterest> 

</sos:GetObservation> 

<temporalFilter>节点可以通过更换:

<temporalFilter> 
    <fes:Before> 
     <fes:ValueReference>phenomenonTime</fes:ValueReference> 
     <gml:TimeInstant gml:id="endPosition"> 
      <gml:timePosition>2010-07-31T01:05:00</gml:timePosition> 
     </gml:TimeInstant> 
    </fes:Before> 
</temporalFilter> 

或者:

<temporalFilter> 
    <fes:During> 
     <fes:ValueReference>phenomenonTime</fes:ValueReference> 
     <gml:TimePeriod gml:id="duringPosition"> 
      <gml:beginPosition>2010-07-31T01:05:00</gml:beginPosition> 
      <gml:endPosition>2010-07-31T01:06:00</gml:endPosition> 
     </gml:TimePeriod> 
    </fes:During> 
</temporalFilter> 

下面的LINQ to XML代码工作,但我需要的代码能够处理任何三个temporalFilter的可能性我上面列出。有人有任何建议吗?

private void GetTemporalFilterFromXml(GetObservation getObservation) 
    { 
     //var root = XElement.Load(@"C:\Working Directory\OGCSOS.Service\OGCSOS.Service\Resources\GetObservation_TemporalFilter.xml"); 
     var root = XElement.Parse(getObservation.ToXml(false, Formatting.None, EOLType.CRLF, RequestHandler.GetSos20Context())); 
     GetTemporalFilterDescendant(root); //Test line of code! 
     var query = (from level in root.Descendants(sos + "temporalFilter") 
        select new 
        { 
         valueReference = (string)level.Descendants(fes + "ValueReference").FirstOrDefault(), 
         timeInstant = (string)level.Descendants(gml + "TimeInstant").First().Attribute(gml + "id"), 
         timePosition = (string)level.Descendants(gml + "TimeInstant").Descendants(gml + "timePosition").First() 
        }).ToList(); 
     if (query.Any() == false) return; 
     if (!String.IsNullOrEmpty(query[0].valueReference)) ValueReference = query[0].valueReference; 
     if (!String.IsNullOrEmpty(query[0].timePosition)) TimePosition = query[0].timePosition; 
     if (!String.IsNullOrEmpty(query[0].timeInstant)) TimeInstant = query[0].timeInstant; 
    } 

编辑:这是我使用,以捕捉一切,我需要

{ 
     //var root = XElement.Load(@"C:\Working Directory\OGCSOS.Service\OGCSOS.Service\Resources\GetObservation_TemporalFilter.xml"); 
     var root = XElement.Parse(getObservation.ToXml(false, Formatting.None, EOLType.CRLF, RequestHandler.GetSos20Context())); 
     var query = (from x in root.Descendants(sos + "temporalFilter").Elements() 
        let timeInstant = x.Element(gml + "TimeInstant") 
        let timePeriod = x.Element(gml + "TimePeriod") 
        select new 
        { 
         valueReference = (string)x.Element(fes + "ValueReference"), 
         timeInstant = (timeInstant == null) ? null : timeInstant.Attribute(gml + "id").Value, 
         timePosition = (timeInstant == null) ? null : timeInstant.Element(gml + "timePosition").Value, 
         timePeriod = (timePeriod == null) ? null : timePeriod.Attribute(gml + "id").Value, 
         beginPosition = (timePeriod == null) ? null : timePeriod.Element(gml + "beginPosition").Value, 
         endPosition = (timePeriod == null) ? null : timePeriod.Element(gml + "endPosition").Value, 
        }).ToList(); 

     if (query.Count == 0) return; 
     ValueReference = query[0].valueReference; 
     TimeInstant = query[0].timeInstant; 
     TimePosition = query[0].timePosition; 
     TimePeriod = query[0].timePeriod; 
     BeginTime = query[0].beginPosition; 
     EndTime = query[0].endPosition; 
    } 
+0

我想在我的代码中使用where语句,但无济于事。即使是我应该尝试的简单建议也足够了。 – Jollyra

+0

为了澄清,我希望代码首先检查“after”,“before”或“during”节点是否存在,然后继续相应地解析XML。 – Jollyra

+0

''没有'TimeInstant'元素。你的属性应该如何映射到该节点? –

回答

2

这将做的工作数据的代码。 Elements()将返回所有三种类型的节点 - 之前,之后和期间。引入新的范围变量timeInstant允许检查,如果这个节点元素存在,处理过程中的节点:

var query = from x in root.Descendants(sos + "temporalFilter").Elements() 
      let timeInstant = x.Element(gml + "TimeInstant") 
      select new 
      { 
       valueReference = (string)x.Element(fes + "ValueReference"), 
       timeInstant = (timeInstant == null) ? null : (string)timeInstant.Attribute(gml + "id"), 
       timePosition = (timeInstant == null) ? null : (string)timeInstant.Element(gml + "timePosition") 
      }; 

BTW你可以投timePosition(DateTime?)和LINQ会给你好看DateTime对象。

+0

这看起来像我所需要的。我会尝试与此合作。 – Jollyra

+0

你是一个疯子:像魅力一样工作! – Jollyra