Reputation: 527
I have problems nesting elements using XSLT.
I have read enter link description here, this seems the same issue as I have, but I can't get it to work properly.
My XSLT (simplified)
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<!--https://www.onenaught.com/posts/23/xslt-tips-for-cleaner-code-and-better-performance#toc-avoid-xslfor-each-use-template-match -->
<xsl:template match="/">
<Root xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.aca.nl/schema/weborder">
<Session GenerationDate="{format-dateTime(current-dateTime(),'[Y0001][M01][D01]T[H01]:[m01]:[s01]')}"
SessionNr=""
InterfaceRelease="3.0.0"
SessionId="">
</Session>
<xsl:apply-templates/>
</Root>
</xsl:template>
<xsl:template match="ORDER_DATA">
<DocumentHeader
DocumentNo="{TB_ID}"
ExternalRecordId="{TB_ID}"
ExternalWebshopId="{CHANNEL_SIGN}"
ExternalOrderNo="{TB_ID}"
PricesIncludingVat="1"
SequenceNumber="22221"
ExternalChannelIdentifier="4821476634">
<CustomerData>
<xsl:apply-templates select="SELL_TO"/>
</CustomerData>
</DocumentHeader>
</xsl:template>
<xsl:template match="SELL_TO">
<SellToData SellToSalutationCode=""
SellToFirstName="{FIRSTNAME}"
SellToMiddleName="*"
SellToSureName="{LASTNAME}"
SellToStreet="{STREET_NO}"
SellToPostCode="{ZIP}"
SellToHouseNo=""
SellToHouseNoAddition=""
SellToCity="{CITY}"
SellToCountry="{COUNTRY}"
SellToPhoneNo="{PHONE_PRIVATE}"
SellToEmail="{EMAIL}">
</SellToData>
</xsl:template>
</xsl:stylesheet>
I would expect the SELL_TO item would be rendered between the CustomData-tags but in the outputted file (see result below), the SELL_TO info is rendered after the CustomData-tag even after Documentheader-tag.
<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.aca.nl/schema/weborder">
<Session GenerationDate="20190927T11:29:01"
SessionNr=""
InterfaceRelease="3.0.0"
SessionId=""
/>
<DocumentHeader xmlns=""
DocumentNo="6130"
ExternalRecordId="6130"
ExternalWebshopId="amde"
ExternalOrderNo="6130"
PricesIncludingVat="1"
SequenceNumber="22221"
ExternalChannelIdentifier="4821476634">
<CustomerData/>
</DocumentHeader>
<SellToData xmlns=""
SellToSalutationCode=""
SellToFirstName="Max"
SellToMiddleName="*"
SellToSureName="Mustermann"
SellToStreet="Bahnhofsplatz 8"
SellToPostCode="66882"
SellToHouseNo=""
SellToHouseNoAddition=""
SellToCity="Ansbach"
SellToCountry="DE"
SellToPhoneNo="049123456789"
SellToEmail="[email protected]"/>
</Root>
Can someone tell what is wrong with my XSLT code?
Update:
The input XML (Part of)
<?xml version="1.0" encoding="UTF-8"?>
<ORDER_LIST>
<ORDER xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ORDER_DATA>
<ORDER_DATE>2019-09-10</ORDER_DATE>
<TB_ID>6130</TB_ID>
<CHANNEL_SIGN>amde</CHANNEL_SIGN>
<CHANNEL_ID>302-1961532-0413146</CHANNEL_ID>
<CHANNEL_NO>302-1961532-0413146</CHANNEL_NO>
<PAID>0</PAID>
<APPROVED>1</APPROVED>
<ITEM_COUNT>1</ITEM_COUNT>
<TOTAL_ITEM_AMOUNT>27.50</TOTAL_ITEM_AMOUNT>
<DATE_CREATED>2019-09-10T17:36:19</DATE_CREATED>
</ORDER_DATA>
<SELL_TO>
<TB_ID>6744</TB_ID>
<FIRSTNAME>Max</FIRSTNAME>
<LASTNAME>Mustermann</LASTNAME>
<NAME>Max Mustermann</NAME>
<STREET_NO>Bahnhofsplatz 8</STREET_NO>
<ZIP>66882</ZIP>
<CITY>Ansbach</CITY>
<COUNTRY>DE</COUNTRY>
<PHONE_PRIVATE>049123456789</PHONE_PRIVATE>
<PHONE_OFFICE>049 123456789</PHONE_OFFICE>
<PHONE_MOBILE>+49 123456789</PHONE_MOBILE>
<EMAIL>[email protected]</EMAIL>
</SELL_TO>
</ORDER>
</ORDER_LIST>
Upvotes: 0
Views: 62
Reputation: 117083
In order to move the (processed results of) SELL_TO
to the CustomerData
element, you must do two things:
Point your xsl:apply-templates
instruction to the correct path to the node -
i.e. change:
<CustomerData>
<xsl:apply-templates select="SELL_TO"/>
</CustomerData>
to:
<CustomerData>
<xsl:apply-templates select="../SELL_TO"/>
</CustomerData>
Remove the SELL_TO
element from the default processing order by
adding the following template:
<xsl:template match="ORDER">
<xsl:apply-templates select="ORDER_DATA"/>
</xsl:template>
Otherwise it will be processed twice.
Alternatively, change the instruction:
<xsl:apply-templates/>
in your main template to:
<xsl:apply-templates select="ORDER_LIST/ORDER/ORDER_DATA"/>
Upvotes: 1