【问题标题】:Xpath to get an the parent node where two attributes of a sub node have a particular valueXpath 获取父节点,其中子节点的两个属性具有特定值
【发布时间】: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);

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

【问题讨论】:

    标签: c# xml xpath xml-namespaces xmldocument


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-30
      相关资源
      最近更新 更多