0

The source xml can come with a different ns prefix for the NativeTrxDetail node in the sample below:

<?xml version="1.0" encoding="UTF-8"?>
<VLog xmlns="http://www.university.com/integration/" xmlns:tri="http://www.university.com/integration/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" GeneratingCodeVersion="2.5.2.0.717" Version="1.0"
        xsi:schemaLocation="http://www.university.com/integration/VLog.xsd">
    <Header>
        <MessageId>08c5a8c055a685d6a71a77</MessageId>
        <Timestamp>2016-03-17T16:00:01</Timestamp>
    </Header>
    <Body>
        <tri:Transaction xmlns="http://www.f-arts.org/namespace/" Version="1.0" xsi:type="RetailTransactionStockView">
            <RetailStoreID>Bud053</RetailStoreID>
            <WorkstationID>1</WorkstationID>
            <tri:NativeTrxDetail>
                <tri:ApplicationID>POS</tri:ApplicationID>
                <tri:OrganizationID>Bud</tri:OrganizationID>
                <tri:TillCharacteristics>
                    <tri:TillDeviceID/>
                    <tri:TillOperatorID/>
                </tri:TillCharacteristics>
            </tri:NativeTrxDetail>
            <OperatorID>92053</OperatorID>
            <CurrencyCode>NZD</CurrencyCode>
            <TillID>770</TillID>
            <TillSupervisor>92053</TillSupervisor>
            <LineItem>
                <SequenceNumber>1</SequenceNumber>
                <EndDateTime>2016-08-17T16:00:33</EndDateTime>
                <tri:NativeLineDetail>
                    <tri:LineNumber>29</tri:LineNumber>
                    <tri:LineType>CurrentTransaction</tri:LineType>
                    <tri:ActionCode>POST_VOID_SALE</tri:ActionCode>
                </tri:NativeLineDetail>
                <SupplementalData/>
                <Command/>
            </LineItem>
            <Total TotalType="TransactionGrandAmount">
                <Amount>-0.55</Amount>
            </Total>
            <TransactionLink ReasonCode="PostVoid">
                <BusinessDayDate>2016-08-17</BusinessDayDate>
            </TransactionLink>
        </tri:Transaction>
    </Body>
</VLog>

I need to change the ns for just NativeTrxDetail though there are other nodes/elements with tri.

Output needed is:

<?xml version="1.0"?>
<ns0:VLog xmlns:b="http://www.f-arts.org/namespace/" xmlns:a="http://www.university.com/integration/" xmlns:ns1="http://www.f-arts.org/namespace/" xmlns:ns0="http://www.university.com/integration/">
    <ns0:Header>
        <ns0:MessageId>08c5a8c055a685d6a71a77</ns0:MessageId>
        <ns0:Timestamp>2016-03-17T16:00:01</ns0:Timestamp>
    </ns0:Header>
    <ns0:Body>
        <ns0:Transaction>
            <ns1:RetailStoreID>Bud053</ns1:RetailStoreID>
            <ns1:WorkstationID>1</ns1:WorkstationID>
            <ns1:NativeTrxDetail>
                <ns0:ApplicationID>POS</ns0:ApplicationID>
                <ns0:OrganizationID>Bud</ns0:OrganizationID>
            </ns1:NativeTrxDetail>
        </ns0:Transaction>
    </ns0:Body>
</ns0:VLog>

I am able to achieve this by the following:

<?xml version='1.0' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="http://www.university.com/integration/" xmlns:ns1="http://www.f-arts.org/namespace/" xmlns:b="http://www.f-arts.org/namespace/">
    <xsl:template match="/">
        <ns0:VLog xmlns:ns0="http://www.university.com/integration/">
            <ns0:Header>
                <ns0:MessageId>
                    <xsl:value-of select="//*[local-name()='MessageId']"/>
                </ns0:MessageId>
                <ns0:Timestamp>
                    <xsl:value-of select="//*[local-name()='Timestamp']"/>
                </ns0:Timestamp>
            </ns0:Header>
            <ns0:Body>
                <ns0:Transaction>
                    <ns1:RetailStoreID>
                        <xsl:value-of select="//*[local-name()='RetailStoreID']"/>
                    </ns1:RetailStoreID>
                    <ns1:WorkstationID>
                        <xsl:value-of select="//*[local-name()='WorkstationID']"/>
                    </ns1:WorkstationID>
                    <ns1:NativeTrxDetail>
                        <ns0:ApplicationID>
                            <xsl:value-of select="//*[local-name()='ApplicationID']"/>
                        </ns0:ApplicationID>
                        <ns0:OrganizationID>
                            <xsl:value-of select="//*[local-name()='OrganizationID']"/>
                        </ns0:OrganizationID>
                    </ns1:NativeTrxDetail>
                </ns0:Transaction>
            </ns0:Body>
        </ns0:VLog>
    </xsl:template>
</xsl:stylesheet>

I need to make it such that I don't need to map each element one by one because there are many such nodes in the source xml that would need the same treatment.

I tried the code below but it doesn't work:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tri="http://www.university.com/TE/integration/" xmlns:ns1="http://www.university.com/integration/" xmlns = "http://www.f-arts.org/namespace/" >
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>
    <!-- template to handle elements -->
    <xsl:template match="tri:NativeTrxDetail">
        <xsl:element name="ns1:{local-name()}">
            <xsl:apply-templates select="node() | @*"/>
        </xsl:element>
    </xsl:template>
      <xsl:template match="@tri:NativeTrxDetail">
    <xsl:attribute name="ns1:{local-name()}">
      <xsl:value-of select="." />
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

please help.

Thanks n regards Bhamber

5
  • "because there are many such nodes in the source xml that would need the same treatment" - how would you identify which need "the same treatment" and which don't? Commented Sep 13, 2016 at 9:36
  • This is for a mapping in SAP PI. We already have an xsd and we are going to map the incoming xml to that xsd. So basically we know what is the required target. the source is a bit tricky. Commented Sep 13, 2016 at 9:42
  • Please post a Minimal, Complete, and Verifiable example Commented Sep 13, 2016 at 10:36
  • its minimal... actual xml has over 1000 elements. Just trying transformation on one node and its elements. There are 2 XSLT codes provided, first one works as it is field to field and the output for the same has been provided as the required output. 2nd XSLT code is not giving the correct output. Hence, its output has not been posted to make the post minimal :) Commented Sep 13, 2016 at 10:47
  • minimal in the sense of what michael.hor257k states as "Also it would be helpful to reduce the example to only one or two elements of each namespace." Commented Sep 13, 2016 at 15:50

1 Answer 1

1

Your question is confusing. You say you only want to change the namespace of NativeTrxDetail, but your output adds or changes namespace prefixes of all nodes - and with no apparent reason. And not all nodes are passed to the output.

The prefix assigned to a namespace has no significance, so the requested task could be achieved quite simply by:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:univ="http://www.university.com/integration/"
exclude-result-prefixes="univ">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="univ:NativeTrxDetail">
    <NativeTrxDetail xmlns="http://www.f-arts.org/namespace/">
        <xsl:apply-templates select="@*|node()"/>
    </NativeTrxDetail>
</xsl:template>

</xsl:stylesheet>

This will work no matter what prefix the source XML assigns to NativeTrxDetail, as long as it is bound to the "http://www.university.com/integration/"> namespace URI.

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

5 Comments

Hi Michael... yes, the other nodes and elements have their ns changed as well. That is also a part of the actual requirement and I am able to achieve that BUT the NativeTrxDetail is actually tricky for me as the elements in it have different ns 'ns0', just like Header, Body and Transaction. Rest is all 'ns1'. In the source 'tri' comes in all the elements of 'NativeTrxDetail'.
You need to restate your requirements. Also it would be helpful to reduce the example to only one or two elements of each namespace. -- Note that changing the prefix but retaining the same namespace URI does not really accomplish anything.
your code just removes the ns 'tri' but aint appending any ns0 or ns1 as in the required output... nice to c u again :)
@Bhamber Perhaps you have missed this part of my answer: "The prefix assigned to a namespace has no significance." My code moves the NativeTrxDetail from the "http://www.university.com/integration/" namespace to the "http://www.f-arts.org/namespace/" namespace - and that's all that should matter here.
Once again, thanks @michael.hor257k :) i read ur comment but got busy editing the post as suggested by u... anyhow, U R THE MAN!!

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.