0

I have one xml A and want to create a new xml B. The outer elements of B are different from A, but some of the child nodes are the same. I have written an XSL file but am struggling to get it right. Can anyone tell me where I am going wrong? How do I copy individual elements from A to B? The issue is, when the transformation happens, the text in A is copied to B. Looking at previous stack overflow questions, this is because there is an error in my xsl but I cant figure out what.

A:

<Request>
    <Source>
        <RequestorID Client="1" EMailAddress="[email protected]" Password="pwd"/>
        <RequestorPreferences Country="JP" Currency="jpy" Language="en">
            <RequestMode>SYNCHRONOUS</RequestMode>
        </RequestorPreferences>
    </Source>
    <RequestDetails>
        <SearchHotelPriceRequest>
            <ItemDestination DestinationCode="LON" DestinationType="city"/>
            <ItemCode>98i</ItemCode>
            <PeriodOfStay>
                <CheckInDate>2015-05-20</CheckInDate>
                <CheckOutDate>2015-05-21</CheckOutDate>
            </PeriodOfStay>
            <IncludePriceBreakdown/>
            <IncludeChargeConditions/>
            <Rooms>
                <Room Code="tb" NumberOfCots="0" NumberOfRooms="1">
                    <ExtraBeds/>
                </Room>
            </Rooms>
        </SearchHotelPriceRequest>
    </RequestDetails>
</Request>

B:

<WebRequest>
    <RequestDetails>
        <WebSearchHotelPriceRequest
                CallCentreClientUI="2577"
                Client="1"
                Country="JP"
                Currency="jpy"
                Language="en"
                LoginID="">
            <GcPriceOptions ShowDeduped="true"/>
            <ItemDestination DestinationCode="LON" DestinationType="city"/>
            <ItemName></ItemName>
            <ItemCode>98i</ItemCode>
            <EffectiveDate>2014-08-15</EffectiveDate>
            <StarRatingRange>
                <Min>0</Min>
                <Max>0</Max>
            </StarRatingRange>
            <PeriodOfStay>
                <CheckInDate>2015-05-20</CheckInDate>
                <CheckOutDate>2015-05-21</CheckOutDate>
            </PeriodOfStay>
            <IncludeChargeConditions/>
            <Rooms>
                <Room Code="tb" NumberOfRooms="1"></Room>
            </Rooms>
            <SiteId>008</SiteId>
        </WebSearchHotelPriceRequest>
    </RequestDetails>
</WebRequest>

XSL:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="Request">
        <xsl:element name="WebRequest">
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>

    <xsl:template match="RequestDetails">
        <xsl:element name="RequestDetails">
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>

    <xsl:template match="SearchHotelPriceRequest">
        <xsl:element name="WebSearchHotelPriceRequest">
            <xsl:attribute name="CallCentreClientUI">1</xsl:attribute>
            <xsl:attribute name="Client">1</xsl:attribute>
            <xsl:attribute name="Country">UK</xsl:attribute>
            <xsl:attribute name="Currency">GBP</xsl:attribute>
            <xsl:attribute name="Language">EN</xsl:attribute>
            <xsl:attribute name="LoginID">100</xsl:attribute>

            <SiteId>001</SiteId>
            <EffectiveDate>01-01-99</EffectiveDate>
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>

    <xsl:template match="ItemDestination">
        <xsl:copy>
            <xsl:copy-of select="@*" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ItemCode">
        <xsl:copy>
            <xsl:copy-of select="@*" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ItemName">
        <xsl:copy>
            <xsl:copy-of select="@*" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="PeriodOfStay">
        <xsl:copy>
            <xsl:copy-of select="node()" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="IncludeChargeConditions">
        <xsl:copy>
            <xsl:copy-of select="node()" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Rooms">
        <xsl:copy>
            <xsl:copy-of select="node()" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet> 

Incorrect Output:

<?xml version="1.0" encoding="UTF-8"?>
<WebRequest>SYNCHRONOUS<RequestDetails>
<WebSearchHotelPriceRequest CallCentreClientUI="1" Client="1" Country="UK" Currency="GBP" Language="EN" LoginID="100">
<SiteId>001</SiteId>
<EffectiveDate>01-01-99</EffectiveDate>
<ItemDestination DestinationCode="LON" DestinationType="city"/>
<ItemCode>98i</ItemCode>
<PeriodOfStay>
<CheckInDate>2015-05-20</CheckInDate>
<CheckOutDate>2015-05-21</CheckOutDate>2015-05-202015-05-21</PeriodOfStay>
<IncludeChargeConditions/>
<Rooms>
<Room Code="tb" NumberOfCots="0" NumberOfRooms="1">
<ExtraBeds/>
</Room>
</Rooms>
</WebSearchHotelPriceRequest>
</RequestDetails>
</WebRequest>
5
  • Why are the values of pretty much all elements common to both input A and output B not the same? Commented Aug 31, 2014 at 18:29
  • Xml B is just a sample.. It's the tags and values in A that are important. Commented Aug 31, 2014 at 18:41
  • 2
    Do not make it so hard for people to help you. Present an XML output that is exactly the result of transforming the input XML you show. Commented Aug 31, 2014 at 18:43
  • This is impossible to follow: for example, your XSLT has `WebSearchHotelPriceRequest/@Currency hardcoded as "GBP"; your requested output shows "USD". I think the correct value in your input is "jpy". Commented Aug 31, 2014 at 19:00
  • Fixed the values in B. As I said, its the elements I'm more interested in. If someone could tell me why the extra text (e.g. SYNCHRONOUS) is being erroneously copied? Commented Aug 31, 2014 at 19:09

1 Answer 1

1

I think you are making this much more complicated than it needs to be. The simplest way to copy elements (along with all they contain, i.e. "deep copy") is to use xsl:copy-of. Also, you don't need to use xsl:element if you know the name of the element; just output the element literally. Similarly, for xsl:attribute you can write it directly and - if necessary - use attribute value template to insert the value from the input.

Have a look at the following stylesheet as an example:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
    <WebRequest>
        <xsl:for-each select="Request/RequestDetails/SearchHotelPriceRequest">
            <RequestDetails>
                <WebSearchHotelPriceRequest
                    CallCentreClientUI="2577"
                    Client="2577"
                    Country="J"
                    Currency="USD"
                    Language="E"
                    LoginID="">
                    <GcPriceOptions ShowDeduped="true"/>
                    <xsl:copy-of select="ItemDestination"/>
                    <ItemName></ItemName>
                    <xsl:copy-of select="ItemCode"/>
                    <EffectiveDate>2014-08-15</EffectiveDate>
                    <StarRatingRange>
                        <Min>0</Min>
                        <Max>0</Max>
                    </StarRatingRange>
                    <xsl:copy-of select="PeriodOfStay | IncludeChargeConditions | Rooms"/>
                    <SiteId>008</SiteId>
                </WebSearchHotelPriceRequest>
            </RequestDetails>
        </xsl:for-each>
    </WebRequest>
</xsl:template>

</xsl:stylesheet>

This is of course not exactly what you need, but I don't know which values go where.

If someone could tell me why the extra text (e.g. SYNCHRONOUS) is being erroneously copied?

Because you are using xsl:apply templates indiscriminately - and text nodes are copied by default using the built-in templates.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.