Im trying to transform an XML doc where there is an address node that has child elements Address[1-9]
currently, Im using the following xslt to concatenate all the lines into a single output
out:AddressLine
<xsl:value-of select=”$nodeOfAddress/*[starts-with(name(), ‘in:AddressLine’)]/text()[normalize-space()]/normalize-space()” separator=” “/>
</out:AddressLine>
This seems to work great for ALL address lines. However, I only want to do this for lines 3-6, not all 9 of them. Is there a way specify that in the for each select? Im sure I could hack out a way with a few if statements, but was hoping maybe there is a way similar to what I have above.
I was asked for a sample in file. I looks something like this
<in:AddressNode>
<in:AddressLine1>Value1</in:AddressLine1>
<in:AddressLine2>Value1</in:AddressLine2>
<in:AddressLine3>Value1</in:AddressLine3>
<in:AddressLine4>Value1</in:AddressLine4>
<in:AddressLine5>Value1</in:AddressLine5>
<in:AddressLine6>Value1</in:AddressLine6>
<in:AddressLine7>Value1</in:AddressLine7>
<in:AddressLine8>Value1</in:AddressLine8>
<in:AddressLine9>Value1</in:AddressLine9>
</in:AddressNode>
I just want address3, 4, 5, and 6
5
Maybe:
<xsl:value-of select="$NodeOfAddress/*[starts-with(name(), 'in:AddressLine')][3 le position() and position() le 6]" />
Hard to be sure without seeing the input.
0
You can use the sequence (3, 4, 5, 6)
(which I’ve written below in the equivalent form (3 to 6)
) in your predicate to select the AddressLine child elements by position()
e.g.:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:out="out"
xmlns:in="in">
<xsl:template match="/">
<xsl:variable name="nodeOfAddressLine" select="in:AddressNode/*"/>
<out:AddressLine><xsl:value-of
select="$nodeOfAddressLine[position()=(3 to 6)]"
separator=" "
/></out:AddressLine>
</xsl:template>
</xsl:stylesheet>
That’s assuming that your sample input is really representative, and that the only children of AddressNode
are the AddressLine elements you want. But if that the AddressNode
element does have other children, then you’d need to select only the ones whose names start with AddressLine
, e.g.
<xsl:variable name="nodeOfAddressLine"
select="in:AddressNode/*[starts-with(local-name(), 'AddressLine')]"/>
Personally I would probably just explicitly select the various AddressLine elements by name, if there are only 4 different elements, as I think it makes the intent clearer.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:out="out"
xmlns:in="in">
<xsl:template match="/">
<out:AddressLine><xsl:value-of
select="in:AddressNode/
(in:AddressLine3 | in:AddressLine4 | in:AddressLine5 | in:AddressLine6)"
separator=" "
/></out:AddressLine>
</xsl:template>
</xsl:stylesheet>
If the prefix: in
in your xml and/or the positions of your child-elements can vary, I would use this:
<xsl:value-of select="$NodeOfAddress/*[number(substring-after(name(),'AddressLine')) = (3 to 6)]" />