Jump to content

xslt position() usage


genox

Recommended Posts

Hi All,I'm creating an XSL script to convert some XML for a system integration project and thanks to the help of users on this forum am making some good progress (this is my first foray into XML/XSLT)My latest issue has to do with the structure of the source XML. I have 2 sets of addresses held under the path PO/ADDRESS, one for Billing To and the other for Shipping To. The order of the addresses is fixed in the source, Bill To addresses first and Ship To addresses second reading top to bottom i.e.Excerpt from Source XML

<ADDRESS>        <ADDRESS1>Lumford Mill,</ADDRESS1>        <ADDRESS2>Buxton Road</ADDRESS2>        <ADDRESS3 />        <ADDRESS4>Bakewell</ADDRESS4>        <ADDRESS5 />        <ADDRESS6>DE45 1GS</ADDRESS6>        <ADDRESS7 />        <ADDRESSCODE>BAKEWELL</ADDRESSCODE>        <ADDRESSID>741</ADDRESSID>        <BUILDINGNAME>Bakewell</BUILDINGNAME>        <BUILDINGSC>BAKEWELL</BUILDINGSC>        <CHANGEBY>MXINTADM</CHANGEBY>        <CHANGEDATE>2009-10-27T12:50:07+00:00</CHANGEDATE>        <DESCRIPTION />        <HASLD>0</HASLD>        <LANGCODE>EN</LANGCODE>        <ORGID>IBM</ORGID>        <REMARKS />      </ADDRESS>      <ADDRESS>        <ADDRESS1>5th floor,</ADDRESS1>        <ADDRESS2>1 Redcliff Street</ADDRESS2>        <ADDRESS3 />        <ADDRESS4>Bristol</ADDRESS4>        <ADDRESS5 />        <ADDRESS6>BS1 6NP</ADDRESS6>        <ADDRESS7 />        <ADDRESSCODE>1 REDCLIFFE</ADDRESSCODE>        <ADDRESSID>726</ADDRESSID>        <BUILDINGNAME>1 Redcliffe (Ex Ca/CRC site)</BUILDINGNAME>        <BUILDINGSC>1 REDCLIFFE</BUILDINGSC>        <CHANGEBY>MXINTADM</CHANGEBY>        <CHANGEDATE>2009-10-27T12:50:06+00:00</CHANGEDATE>        <DESCRIPTION />        <HASLD>0</HASLD>        <LANGCODE>EN</LANGCODE>        <ORGID>IBM</ORGID>        <REMARKS>(Ex CA/CRC site)</REMARKS>      </ADDRESS>

I know about the position() function to select a tags position using the xsl:templates-match and xsl:apply-templates tags (i.e. <xsl:apply-templates select="ADDRESS[position() = 2]"/> selects the second set ) which I've been told is the best way. My problem with using that is that my xsl script has a single xsl-template-match statement at the top and closed off at the bottom so entering a nested xsl-template:match statement causes an error.Is there another way (or a way of using position() or a similar function) to specify the first or second set of address tags on demand?Excerpt of xsl

<!-- *** ShipTo section starts here *** -->				<ShipTo>		<xsl:element name="Address">			<xsl:attribute name="addressID"><xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:SHIPTO"/></xsl:attribute>			<xsl:attribute name="isoCountryCode">GB</xsl:attribute>		</xsl:element> 			<xsl:element name="Name">			<xsl:attribute name="xml:lang">en</xsl:attribute>						<!--			***** need to find a way to skip first ADDRESS/ADDRESS1 - which is BILLTO address,  to second ADDRESS/ADDRESS1 - which is SHIPTO address *****						<xsl:if test="position()!=first()">				<xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS1"/> 			</xsl:if>						<xsl:template match="mx:ADDRESS">			<xsl:apply-templates select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS1[position() = 2]"/> -->			<xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS1"/>			<!--</xsl:template> -->		</xsl:element> 						<xsl:element name="PostalAddress">			<xsl:attribute name="default"></xsl:attribute>				<DeliverTo><xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:SHIPTOATTN"/></DeliverTo> <!-- DeliverTo tags in twice - have set first one to SHIPTOATTN -->				<DeliverTo><xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS1[last()]"/></DeliverTo>				<Street><xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS2[last()]"/></Street>				<City><xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS4[last()]"/></City>				<State>XXXX</State> <!-- Check this one -->				<PostalCode><xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS6[last()]"/></PostalCode>			<xsl:element name="Country">				<xsl:attribute name="isoCountryCode">GB</xsl:attribute>				Great Britain			</xsl:element>		</xsl:element> 						<xsl:element name="Email">			<xsl:attribute name="name">default</xsl:attribute>			<xsl:attribute name="preferredLang">en-US</xsl:attribute>			<xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:PERSON/mx:IMID"/>		</xsl:element>							</ShipTo>				<!-- *** End of ShipTo section *** -->				<!-- *** BillTo section starts here *** -->				<BillTo>				<xsl:element name="Address">			<xsl:attribute name="addressID"><xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:BILLTO"/></xsl:attribute>			<xsl:attribute name="isoCountryCode">GB</xsl:attribute>		</xsl:element> 			<xsl:element name="Name">			<xsl:attribute name="xml:lang">en</xsl:attribute>							<xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS1"/> 		</xsl:element>						<xsl:element name="PostalAddress">			<xsl:attribute name="default"></xsl:attribute>				<DeliverTo><xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:BILLTOATTN"/></DeliverTo> <!-- DeliverTo tags in twice - have set first one to BILLTOATTN -->				<DeliverTo><xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS1"/></DeliverTo>				<Street><xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS2"/></Street>				<City><xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS4"/></City>				<State>XXXX</State> <!-- Check this one -->				<PostalCode><xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS6"/></PostalCode>			<xsl:element name="Country">				<xsl:attribute name="isoCountryCode">GB</xsl:attribute>				Great Britain			</xsl:element>		</xsl:element> 								</BillTo>

Excerpt of output XML

<ShipTo><Address addressID="1 REDCLIFFE" isoCountryCode="GB"/><Name xml:lang="en">Lumford Mill,</Name><PostalAddress default=""><DeliverTo>BU - AEQ</DeliverTo><DeliverTo>Lumford Mill,</DeliverTo><Street>Buxton Road</Street><City>Bakewell</City><State>XXXX</State><PostalCode>DE45 1GS</PostalCode><Country isoCountryCode="GB">				Great Britain			</Country></PostalAddress><Email name="default" preferredLang="en-US">xxxx.xxxx@xxxxx.xxx.xxx</Email></ShipTo><BillTo><Address addressID="BAKEWELL" isoCountryCode="GB"/><Name xml:lang="en">Lumford Mill,</Name><PostalAddress default=""><DeliverTo>PMPRBOWNUSR</DeliverTo><DeliverTo>Lumford Mill,</DeliverTo><Street>Buxton Road</Street><City>Bakewell</City><State>XXXX</State><PostalCode>DE45 1GS</PostalCode><Country isoCountryCode="GB">				Great Britain			</Country></PostalAddress></BillTo>

I've tried using position() with xsl:value-of-select but this doesn't return anything in the tags specified although it compiles without error, so I'm not sure it can be used with this tag , or else I am using it incorrectlyfor example <xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS1"/> changed to <xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS/mx:ADDRESS1[position() = 2]"/>for the Ship To sectionAny help from the forum, much appreciated!Thanks in advanceEugene

Link to comment
Share on other sites

First of all [position() = 2] can simply be written as [2]. And if you want to select the second ADDRESS element then do that by putting the positional predicate on the right element e.g. you likely want

<xsl:value-of select="mx:MXPO_GOSOPSet/mx:PO/mx:ADDRESS[2]/mx:ADDRESS1"/>

to select the value of the ADDRESS1 child element of the second ADDRESS child element of the PO element.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...