Roshan
Roshan

Reputation: 17

Use map function to change field value using xslt 3.0

I need to map field value from hash table only in Debtor field and other values remains same. I want the all other fields to be as it is and only change the map the debtor fields.

P_BPMapping - {"BANK1":"1","BANK2":"2","BANK3":"3","BANK4":"4"}

My input xml

<?xml version="1.0" encoding="UTF-8"?>
<JECreateRequest>
    <MessageHeader>
    </MessageHeader>
        <JournalEntryCreateRequest>
            <MessageHeader>
                <JournalEntry>
                    <DebtorItem>
                        <Debtor>BANK1</Debtor>
                    </DebtorItem>
                </JournalEntry>
            </MessageHeader>
        </JournalEntryCreateRequest>
                <JournalEntryCreateRequest>
            <MessageHeader>
                <JournalEntry>
                    <DebtorItem>
                        <Debtor>BANK2</Debtor>
                    </DebtorItem>
                    <DebtorItem>
                        <Debtor>BANK1</Debtor>
                    </DebtorItem>
                </JournalEntry>
            </MessageHeader>
        </JournalEntryCreateRequest>
                <JournalEntryCreateRequest>
            <MessageHeader>
                <JournalEntry>
                    <DebtorItem>
                        <Debtor>BANK4</Debtor>
                    </DebtorItem>
                    <DebtorItem>
                        <Debtor>BANK3</Debtor>
                    </DebtorItem>
                    <DebtorItem>
                        <Debtor>BANK1</Debtor>
                    </DebtorItem>
                </JournalEntry>
            </MessageHeader>
        </JournalEntryCreateRequest>
</JournalEntryBulkCreateRequest>

Hash Table BANK1 - 1 BANK2 - 2 BANK3 - 3 BANK4 - 4

My XSLT code - I have tried with this XSLT code and getting error.

<xsl:stylesheet 
    version="3.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Start of enhancement - ValueMapping for Payloution Customer -->
    <xsl:param name="P_BPMapping" />
    <xsl:param name="MapDebitor" as="map(*)" select="parse-json($P_BPMapping)" />
    <!-- End of enhancement -->

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

<!--
<xsl:for-each select ="MessageHeader/JournalEntryCreateRequest/JournalEntry/DebtorItem">
-->
<xsl:template match="MessageHeader">
    <xsl:for-each select ="JournalEntryCreateRequest/JournalEntry/DebtorItem">
            <xsl:template match="Debtor">
                <xsl:copy>
                            <xsl:choose>
                                <xsl:when test="map:get($MapDebitor,Debtor)">
                                        <xsl:value-of select="map:get($MapDebitor,Debtor)" />
                                </xsl:when>
                                <xsl:otherwise>
                                    <error>
                                        <xsl:text>Error in BusinessPartner mapping. Please maintain the mapping for the following debtor: </xsl:text>
                                        <xsl:value-of select="Debtor"/>
                                    </error>
                                </xsl:otherwise>
                            </xsl:choose>               
                
                </xsl:copy>
            </xsl:template>
    </xsl:for-each>        
</xsl:template>
<!--
</xsl:for-each>
-->
</xsl:stylesheet>

Expected output

 <?xml version="1.0" encoding="UTF-8"?>
    <JECreateRequest>
        <MessageHeader>
        </MessageHeader>
            <JournalEntryCreateRequest>
                <MessageHeader>
                    <JournalEntry>
                        <DebtorItem>
                            <Debtor>1</Debtor>
                        </DebtorItem>
                    </JournalEntry>
                </MessageHeader>
            </JournalEntryCreateRequest>
                    <JournalEntryCreateRequest>
                <MessageHeader>
                    <JournalEntry>
                        <DebtorItem>
                            <Debtor>2</Debtor>
                        </DebtorItem>
                        <DebtorItem>
                            <Debtor>1</Debtor>
                        </DebtorItem>
                    </JournalEntry>
                </MessageHeader>
            </JournalEntryCreateRequest>
                    <JournalEntryCreateRequest>
                <MessageHeader>
                    <JournalEntry>
                        <DebtorItem>
                            <Debtor>4</Debtor>
                        </DebtorItem>
                        <DebtorItem>
                            <Debtor>3</Debtor>
                        </DebtorItem>
                        <DebtorItem>
                            <Debtor>1</Debtor>
                        </DebtorItem>
                    </JournalEntry>
                </MessageHeader>
            </JournalEntryCreateRequest>
    </JournalEntryBulkCreateRequest>

Upvotes: 0

Views: 423

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

I would use e.g.

  <xsl:param name="map-data" as="xs:string" expand-text="no">{"BANK1":"1","BANK2":"2","BANK3":"3","BANK4":"4"}</xsl:param>

  <xsl:param name="map" select="parse-json($map-data)"/>
  
  <xsl:template match="Debtor[map:contains($map, .)]">
    <xsl:copy>{$map(.)}</xsl:copy>
  </xsl:template>
  
  <xsl:mode on-no-match="shallow-copy"/>

(with xmlns:map="http://www.w3.org/2005/xpath-functions/map" and expand-text="yes" being declared in the XSLT).

Your code also seems to try to find non-matching Debtors and output some error so perhaps an additional template

  <xsl:template match="Debtor[not(map:contains($map, .))]">
    <xsl:copy>
      <error>Error in BusinessPartner mapping. Please maintain the mapping for the following debtor: {.}</error>
    </xsl:copy>
  </xsl:template>

is needed, though the input/output samples don't show that case.

Online sample demo.

Upvotes: 1

Related Questions