Xpath 获取父节点,其中子节点的两个属性具有特定值

Posted

技术标签:

【中文标题】Xpath 获取父节点,其中子节点的两个属性具有特定值【英文标题】:Xpath to get an the parent node where two attributes of a sub node have a particular value 【发布时间】:2020-06-11 13:20:02 【问题描述】:

鉴于此数据集位于:https://dd.weather.gc.ca/observations/xml/ON/today/today_on_20200129_f.xml

我认为我没有正确处理命名空间,但我不确定在这里做什么。

我如何获得一个 om:member 节点,其中 om:member/om:Observation/om:metadata/set/identification-elements/element/name=wmo_station_number 其值为,例如 71704。

我有这个:

    xml.Load(url);
    var nsmgr = new XmlNamespaceManager(xml.NameTable);
    nsmgr.AddNamespace("om", "http://www.opengis.net/om/1.0");
    nsmgr.AddNamespace("", "http://dms.ec.gc.ca/schema/point-observation/2.1");        
    nsmgr.AddNamespace("gml", "http://www.opengis.net/gml");
    nsmgr.AddNamespace("xlink", "http://www.w3.org/1999/xlink");
    nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
    nsmgr.PushScope();

    //  "Observation//element[@name='identifier']";
    var tmp = xml.SelectSingleNode("//om:member/om:Observation/om:metadata", nsmgr);

我知道这是一种愚蠢的尝试,但似乎只要我尝试没有命名空间前缀的任何东西,我就会得到错误或什么都没有返回。

【问题讨论】:

【参考方案1】:

这是一种使用System.Xml.Linq的方法

string url = "https://dd.weather.gc.ca/observations/xml/ON/today/today_on_20200129_f.xml";
string om = "http://www.opengis.net/om/1.0";
string xmlns = "http://dms.ec.gc.ca/schema/point-observation/2.1";

var doc = XDocument.Load(url);
var members = doc.Root.Elements(XName.Get("member", om));
var member71074 = members.FirstOrDefault(x => x
                      .Element(XName.Get("Observation", om))
                      .Element(XName.Get("metadata", om))
                      .Element(XName.Get("set", xmlns))
                      .Element(XName.Get("identification-elements", xmlns))
                      .Descendants()
                      .Any(y => y.Attribute("name")?.Value == "wmo_station_number" && 
                                y.Attribute("value")?.Value == "71704"));

【讨论】:

谢谢。我将使用它并上船,因为它可以获得我想要的数据。仍然想知道我所做的事情出了什么问题,但无论如何这更好。 @carny666 我做了一个更新,它延长了代码但应该会提高性能,因为这么早使用 .Descendants() 会检查比必要更多的节点。恐怕我不熟悉如何使用 XmlDocument【参考方案2】:

这是应该返回节点的 xpath。

//om:member/om:Observation/om:metadata/set/identification-elements/element[@name='wmo_station_number'][@value='71704']

【讨论】:

感谢您的回答。无论出于何种原因,这对我都不起作用。我的意思是它看起来不错。我一直在玩这样的东西,一旦我引入一个没有前缀的元素名称,它就会返回 null。我认为我的问题与命名空间管理器有关。 I introduce an element name that has no prefix it returns null 你的意思是没有@name 属性? 我认为这会给我一些数据://om:member/om:Observation/om:metadata/set 但我得到的是空值。 set 元素没有前缀。 这很奇怪。我在xpath tester 中尝试您的//om:member/om:Observation/om:metadata/set xpath 时看到了数据【参考方案3】:

也许你可以试试:

//*[@name="wmo_station_number" and @value="71704"]/ancestor::om:member

【讨论】:

以上是关于Xpath 获取父节点,其中子节点的两个属性具有特定值的主要内容,如果未能解决你的问题,请参考以下文章

EasyUI tree 选中父节点子节点全部选中,选中子节点父节点不选中

jstree中想要选中子节点,父节点就会变成选中状态,需要如何修改。

Xpath:从父节点和子节点获取属性

element-ui el-tree选中子节点时默认选择父节点

python--爬虫(XPath与xml类库)

XPath:从子节点获取父节点