Home > Net >  XSL Select value from parent element, if two children have specific values
XSL Select value from parent element, if two children have specific values

Time:08-31

I have the following XML. If an address component element exists that has both a type element with value "sublocality" AND a type element with value "sublocality_level_1", I want to then select that address component's value for long_name.

In the example XML below that would be "Vleuten-De Meern"

What I have tried:

    Dim myXML As New XmlDocument
    Dim responseString As String = "<GeocodeResponse><status>OK</status><result><type>political</type><type>sublocality</type><type>sublocality_level_2</type><formatted_address>De Meern, Utrecht, Netherlands</formatted_address><address_component><long_name>De Meern</long_name><short_name>De Meern</short_name><type>political</type><type>sublocality</type><type>sublocality_level_2</type></address_component><address_component><long_name>Vleuten-De Meern</long_name><short_name>Vleuten-De Meern</short_name><type>political</type><type>sublocality</type><type>sublocality_level_1</type></address_component><address_component><long_name>Utrecht</long_name><short_name>Utrecht</short_name><type>locality</type><type>political</type></address_component><address_component><long_name>Utrecht</long_name><short_name>Utrecht</short_name><type>administrative_area_level_2</type><type>political</type></address_component><address_component><long_name>Utrecht</long_name><short_name>UT</short_name><type>administrative_area_level_1</type><type>political</type></address_component><address_component><long_name>Netherlands</long_name><short_name>NL</short_name><type>country</type><type>political</type></address_component><geometry><location><lat>52.0757940</lat><lng>5.0319779</lng></location><location_type>APPROXIMATE</location_type><viewport><southwest><lat>52.0714898</lat><lng>5.0196140</lng></southwest><northeast><lat>52.0904459</lat><lng>5.0484669</lng></northeast></viewport><bounds><southwest><lat>52.0714898</lat><lng>5.0196140</lng></southwest><northeast><lat>52.0904459</lat><lng>5.0484669</lng></northeast></bounds></geometry><place_id>ChIJx5fkM1RlxkcR_pIQJLtl5Ro</place_id></result></GeocodeResponse>"
    myXML.LoadXml(responseString)

    If myXML.SelectSingleNode("GeocodeResponse/result[address_component[type[. = 'sublocality']] and address_component[type[. = 'sublocality_level_1']]]") IsNot Nothing Then
        Log("found")
        neighborhood = myXML.SelectSingleNode("GeocodeResponse/result[address_component[type[. = 'sublocality']] and address_component[type[. = 'sublocality_level_1']]]/long_name").InnerText            
    Else
        Log("NOT found")
    End If

The element is found, a value "found" is logged, but when I want to retrieve the value I get:

"Object reference not set to an instance of an object."

<GeocodeResponse>
    <status>OK</status>
    <result>
        <type>political</type>
        <type>sublocality</type>
        <type>sublocality_level_2</type>
        <formatted_address>De Meern, Utrecht, Netherlands</formatted_address>
        <address_component>
            <long_name>De Meern</long_name>
            <short_name>De Meern</short_name>
            <type>political</type>
            <type>sublocality</type>
            <type>sublocality_level_2</type>
        </address_component>
        <address_component>
            <long_name>Vleuten-De Meern</long_name>
            <short_name>Vleuten-De Meern</short_name>
            <type>political</type>
            <type>sublocality</type>
            <type>sublocality_level_1</type>
        </address_component>
        <address_component>
            <long_name>Utrecht</long_name>
            <short_name>Utrecht</short_name>
            <type>locality</type>
            <type>political</type>
        </address_component>
        <address_component>
            <long_name>Utrecht</long_name>
            <short_name>Utrecht</short_name>
            <type>administrative_area_level_2</type>
            <type>political</type>
        </address_component>
        <address_component>
            <long_name>Utrecht</long_name>
            <short_name>UT</short_name>
            <type>administrative_area_level_1</type>
            <type>political</type>
        </address_component>
        <address_component>
            <long_name>Netherlands</long_name>
            <short_name>NL</short_name>
            <type>country</type>
            <type>political</type>
        </address_component>
        <geometry>
            <location>
                <lat>52.0757940</lat>
                <lng>5.0319779</lng>
            </location>
            <location_type>APPROXIMATE</location_type>
            <viewport>
                <southwest>
                    <lat>52.0714898</lat>
                    <lng>5.0196140</lng>
                </southwest>
                <northeast>
                    <lat>52.0904459</lat>
                    <lng>5.0484669</lng>
                </northeast>
            </viewport>
            <bounds>
                <southwest>
                    <lat>52.0714898</lat>
                    <lng>5.0196140</lng>
                </southwest>
                <northeast>
                    <lat>52.0904459</lat>
                    <lng>5.0484669</lng>
                </northeast>
            </bounds>
        </geometry>
        <place_id>ChIJx5fkM1RlxkcR_pIQJLtl5Ro</place_id>
    </result>
</GeocodeResponse>

CodePudding user response:

Your path seems wrong, the long_name is a child of address_component; so make sure you select down that path and don't put the relevant elements into a predicate e.g.

Dim name = myXML.SelectSingleNode("GeocodeResponse/result/address_component[type[. = 'sublocality'] and type[. = 'sublocality_level_1']]/long_name")
If name IsNot Nothing Then
  Console.WriteLine("Found: {0}.", name.InnerText)
Else
  Console.WriteLine("Not found.")
  • Related