Reputation: 8731
I have the following xml doc:
<GetGeneralServiceRequestByReferenceValueResponse xmlns="http://www.caps-solutions.co.uk/webservices/connectors/731/servicerequest/messagetypes">
<GeneralServiceRequest xmlns="http://www.caps-solutions.co.uk/schema/uniform/731/servicerequest/sr/srtypes">
<ServiceRequestIdentification>
<ServiceRequestTechnicalKey>PG7ECIJBKFX00</ServiceRequestTechnicalKey>
<ReferenceValue>18/009969/S_SCBC</ReferenceValue>
<AlternativeReferences>
<AlternativeReference xmlns="http://www.caps-solutions.co.uk/schema/uniform/72b/common/uniformtypes">
<ReferenceValue>W44811182451</ReferenceValue>
<ReferenceType>UTRN</ReferenceType>
</AlternativeReference>
<AlternativeReference xmlns="http://www.caps-solutions.co.uk/schema/uniform/72b/common/uniformtypes">
<ReferenceValue>00482</ReferenceValue>
<ReferenceType>BAD</ReferenceType>
</AlternativeReference>
</AlternativeReferences>
<SiteID>JB</SiteID>
</ServiceRequestIdentification>
</GeneralServiceRequest>
</GetGeneralServiceRequestByReferenceValueResponse>
I need to select the <ReferenceValue>
that has a sibling <ReferenceType>
of "UTRN"
The following xpath get's me the <ReferenceValue>
of the last <Alternative>
reference.
/*[local-name()='GetGeneralServiceRequestByReferenceValueResponse']/*[local-name()='GeneralServiceRequest']/*[local-name()='ServiceRequestIdentification']/*[local-name()='AlternativeReferences']/*[local-name()='AlternativeReference']/*[local-name()='ReferenceValue']
I've tried using [] for the parent AlternativeReference node then ReferenceValue='UTRN' but haven't been able to get the required output.
Upvotes: 1
Views: 147
Reputation: 384
This should do:
"//AlternativeReference[1]/ReferenceValue"
Or if you know the sibling value:
"//ReferenceType[text()='UTRN']/parent::*/ReferenceValue"
Upvotes: 1
Reputation: 338316
Don't use local-name()
. Declare the namespaces in your XSLT and use the prefixes.
For example, declare them like this (you can pick any prefixes you like, as long as the namespace URIs match):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msg="http://www.caps-solutions.co.uk/webservices/connectors/731/servicerequest/messagetypes"
xmlns:sr="http://www.caps-solutions.co.uk/schema/uniform/731/servicerequest/sr/srtypes"
xmlns:uni="http://www.caps-solutions.co.uk/schema/uniform/72b/common/uniformtypes"
exclude-result-prefixes="msg sr uni"
>
And use (wrapped for legibility, but XPath is not whitespace-sensitive, you can wrap it the same way in your XSLT):
/msg:GetGeneralServiceRequestByReferenceValueResponse /sr:GeneralServiceRequest /sr:ServiceRequestIdentification /sr:AlternativeReferences /uni:AlternativeReference[uni:ReferenceType = 'UTRN'] /uni:ReferenceValue
Here, /uni:AlternativeReference[uni:ReferenceType = 'UTRN']
only selects those <AlternativeReference>
nodes who have a <ReferenceType>
child of the wanted value.
Since there are many ways to look at an XML tree (and because I think that explicitly. naming. every. single. step. along. the. way. is overdoing it), something like this would also work:
//uni:ReferenceType[. = 'UTRN']/../uni:ReferenceValue
or
//uni:AlternativeReference[uni:ReferenceType = 'UTRN']/uni:ReferenceValue
Upvotes: 2
Reputation: 66783
You can add criteria to the <AlternativeReference>
predicate to restrict the selection of <AlternativeReference>
elements to those that have a <ReferenceType>
element who's value is "UTRN":
/*[local-name()='GetGeneralServiceRequestByReferenceValueResponse']/
*[local-name()='GeneralServiceRequest']/
*[local-name()='ServiceRequestIdentification']/
*[local-name()='AlternativeReferences']/
*[local-name()='AlternativeReference' and *[local-name()='ReferenceType' and .='UTRN']]/
*[local-name()='ReferenceValue']
Upvotes: 2