编辑根据@Gert Arnold的建议,我决定编辑并更彻底地设置我的问题的格式。选择通过Linq在C#中选择两个子节点的节点
我一直在试图通过Linq选择通过id和值条件的节点。在我的情况下,我需要在SeriesKey
节点中具有具有两个特定value
属性的节点的series
。
这里是我的XML字符串(仅供参考,如果你发现任何标记错误,他们可能是由于我的压痕错误,原始文件是XML有效)
<message:GenericData xmlns:footer="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message/footer"
xmlns:generic="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic"
xmlns:message="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message"
xmlns:common="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/common"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<message:DataSet>
<generic:Series>
<generic:SeriesKey>
<generic:Value id="GEO" value="124"/>
<generic:Value id="PRODUCT" value="4400"/>
<generic:Value id="FIN" value="03"/>
<generic:Value id="ENERGY_UNITS" value="WSR"/>
</generic:SeriesKey>
<generic:Obs>
<generic:ObsDimension id="TIME_PERIOD" value="1999"/>
<generic:ObsValue value="0"/>
<generic:Attributes>
<generic:Value id="UNIT_SUFFIX" value="R"/>
</generic:Attributes>
</generic:Obs>
<generic:Obs>
<generic:ObsDimension id="TIME_PERIOD" value="2000"/>
<generic:ObsValue value="0"/>
<generic:Attributes>
<generic:Value id="UNIT_SUFFIX" value="R"/>
</generic:Attributes>
</generic:Obs>
</generic:Series>
<generic:Series>
<generic:SeriesKey>
<generic:Value id="GEO" value="124"/>
<generic:Value id="PRODUCT" value="4100"/>
<generic:Value id="FIN" value="03"/>
<generic:Value id="ENERGY_UNITS" value="WSR"/>
</generic:SeriesKey>
<generic:Obs>
<generic:ObsDimension id="TIME_PERIOD" value="1999"/>
<generic:ObsValue value="8246"/>
<generic:Attributes>
<generic:Value id="UNIT_SUFFIX" value="R"/>
</generic:Attributes>
</generic:Obs>
<generic:Obs>
<generic:ObsDimension id="TIME_PERIOD" value="2000"/>
<generic:ObsValue value="40733"/>
<generic:Attributes>
<generic:Value id="UNIT_SUFFIX" value="R"/>
</generic:Attributes>
</generic:Obs>
</generic:Series>
<generic:Series>
<generic:SeriesKey>
<generic:Value id="GEO" value="124"/>
<generic:Value id="PRODUCT" value="4200"/>
<generic:Value id="FIN" value="03"/>
<generic:Value id="ENERGY_UNITS" value="WSR"/>
</generic:SeriesKey>
<generic:Obs>
<generic:ObsDimension id="TIME_PERIOD" value="1999"/>
<generic:ObsValue value="279"/>
<generic:Attributes>
<generic:Value id="UNIT_SUFFIX" value="R"/>
</generic:Attributes>
</generic:Obs>
<generic:Obs>
<generic:ObsDimension id="TIME_PERIOD" value="2000"/>
<generic:ObsValue value="324"/>
<generic:Attributes>
<generic:Value id="UNIT_SUFFIX" value="R"/>
</generic:Attributes>
</generic:Obs>
</generic:Series>
</message:DataSet>
</message:GenericData>
我试着去查询方式,只是请在where
声明中看到,使用逻辑运算符创建一系列步骤。我已经提到了这个方法。此时它接受一个xml字符串(上面的一个)和两个过滤条件,即EnergyProduct
来过滤PRODUCT
属性和EconSector
以过滤FIN
属性。
public IEnumerable<XElement> DataSetFilter(string XmlString, string EnergyProduct, string EconSector)
{
XDocument sdmx_response = XDocument.Parse(XmlString);
XNamespace message = "http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message";
XNamespace generic = "http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic";
IEnumerable<XElement> DataSet = sdmx_response.Root.Elements(message + "DataSet");
IEnumerable<XElement> Series = from series in DataSet.Elements(generic + "Series")
from serieskey in series.Elements(generic + "SeriesKey")
from value in serieskey.Elements(generic + "Value")
where
(
(string)value.Attribute("id") == "PRODUCT" && (string)value.Attribute("value") == EnergyProduct
) ||
(
(string)value.Attribute("id") == "FIN" && (string)value.Attribute("value") == EconSector
)
select serieskey;
IEnumerable <XElement> observationsSet = from observations in Series.Elements(generic + "Obs").Elements(generic + "ObsValue") select observations;
return observationsSet;
}
的问题是,它抓住了每个属性的所有数据,例如匹配PRODUCT
代码“4400”和FIN
码“03”和我在寻找什么为的那些仅仅是包含节点具有这些确切值的子节点,都在相同的SeriesKey
中。我正在考虑创建一个匿名对象,该对象包含我想要的xml元素,但是我遇到了错误,我仍然对如何正确实现它感到困惑。 谢谢你的帮助!
您的XML无效。如果您将其上传到http://www.xmlvalidation.com,您将看到错误“16:\t 7”\t“元素类型”系列“必须由匹配的结束标记”“终止。”您是否可以共享有效的XML ? – dbc
谢谢。看起来我在粘贴代码时犯了一个错误。在我的情况下,XML验证不是问题。 – Cristiansen
如果您想要满足* both *条件的子节点,不完全确定为什么在'where'子句中使用'||'。 – Tomer