carny666
carny666

Reputation: 2410

Xpath to get an the parent node where two attributes of a sub node have a particular value

Given this dataset at: https://dd.weather.gc.ca/observations/xml/ON/today/today_on_20200129_f.xml

I think I am not dealing with namespaces properly but I am unsure what to do here.

How would I get the an om:member node where om:member/om:Observation/om:metadata/set/identification-elements/element/name=wmo_station_number and it's value is, for example 71704.

I have this:

    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);

I know this is a half witted attempt but it seems as soon as I try anything without a namespace prefix I get errors or just nothing back.

Upvotes: 0

Views: 107

Answers (3)

E.Wiest
E.Wiest

Reputation: 5905

Maybe you can try :

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

Upvotes: 0

Innat3
Innat3

Reputation: 3576

Here's a way using 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"));

Upvotes: 1

supputuri
supputuri

Reputation: 14135

Here is the xpath that should return the node.

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

enter image description here

Upvotes: 0

Related Questions