0

I am working with an xslt file for styling. I am showing some content in tabular format. I need to dynamically populate one column from pre defined key value pair. Please look at below example

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
  <h2>Sample Transformation</h2>
    <table border="1">
    <xyz>msgprop</xyz>
      <tr bgcolor="#9acd32">
        <th>Id</th>
        <th>Name</th>
        <th>City</th>
      </tr>
      <xsl:for-each select="en:MyEvent">
      <tr>
        <td><xsl:value-of select="en:id"/></td>
        <td><xsl:value-of select="en:name"/></td>
        <td><xsl:value-of select="en:country"/></td>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

The problem is that i am receiving country name in place of city and i want to populate the city column with correct city and for that i need to map country and its city. Is there any way to predefined country and its city in key value pair and when received the country name, it will be replaced by city name(if not present it will display country name). Is there any function to do it?. It will be helpfull if you provide a snippet.

Edit: Here is the xml

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <cd>
    <id>Empire Burlesque</id>
    <Name>Bob Dylan</Name>
    <country>USA</country>
  </cd>
  <cd>
    <id>Hide your heart</id>
    <name>Bonnie Tyler</name>
    <country>UK</country>
  </cd>
  <cd>
    <id>Greatest Hits</id>
    <name>Dolly Parton</name>
    <country>USA</country>
  </cd>
  <cd>
    <id>Still got the blues</id>
    <name>Gary Moore</name>
    <country>UK</country>
  </cd>
</catalog>

I need a mapping such that whenever country name is UK it will be replaced with its capital London same with other countries. Is there somew way that i define UK as a key and London as a value so that whenever i received key as UK it will be replaced with its value. Please help.

Anam Qureshi
  • 161
  • 2
  • 8
  • 1
    For XSLT 1 the usual approach is to have your mapping in some XML document (part) and simply use XPath to select the referenced values. XSLT 3 has a `map` data type so there you are not restricted to XML. – Martin Honnen Feb 19 '21 at 13:01
  • Thanks Martin but unfortunately i can not use a seperate xml file. I need to define cities in the same xslt. – Anam Qureshi Feb 19 '21 at 13:13
  • 1
    XSLT is XML so you can define your mapping as part of the XSLT document, either as a parameter or variable or as a top-level, foreign namespace element. It is not sure where you are struggling and what `i am receiving country name in place of city` means, you have not even shown any XML input nor does your XSLT show any country data or attempt to process it. – Martin Honnen Feb 19 '21 at 13:21
  • Edited my question with an example. Please refer – Anam Qureshi Feb 22 '21 at 04:52
  • @MartinHonnen Please have a look at this question. This does look clean. https://stackoverflow.com/questions/66310526/replacing-value-in-xsl-xslt – Anam Qureshi Feb 22 '21 at 06:11
  • Edited again to reclean. Plese suggest. – Anam Qureshi Feb 22 '21 at 07:00

1 Answers1

1

Consider the following example:

XML

<events>
    <event>
        <id>001</id>
        <name>Alpha</name>
        <city>Paris</city>
    </event>
    <event>
        <id>002</id>
        <name>Bravo</name>
        <city>UK</city>
    </event>
    <event>
        <id>003</id>
        <name>Charlie</name>
        <city>Berlin</city>
    </event>
    <event>
        <id>004</id>
        <name>Delta</name>
        <city>USA</city>
    </event>
    <event>
        <id>005</id>
        <name>Echo</name>
        <city>Los Angeles</city>
    </event>
</events>

XSLT 1.0

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

<xsl:template match="/events">
    <html>
        <body>
            <h2>Sample Transformation</h2>
            <table border="1">
                <tr>
                    <th>Id</th>
                    <th>Name</th>
                    <th>City</th>
                </tr>
                <xsl:for-each select="event">
                    <tr>
                        <td>
                            <xsl:value-of select="id"/>
                        </td>
                        <td>
                            <xsl:value-of select="name"/>
                        </td>
                        <td>
                            <xsl:choose>
                                <xsl:when test="city = 'UK'">London</xsl:when>
                                <xsl:when test="city = 'USA'">Washington, D.C.</xsl:when>
                                <!-- add more key/value pairs here -->
                                <xsl:otherwise>
                                    <xsl:value-of select="city"/>
                                </xsl:otherwise>
                            </xsl:choose>
                        </td>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
    </html>
</xsl:template>

</xsl:stylesheet>

Result (rendered):

enter image description here

michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • Thank you so much michael but i tried this already. Problem is that instead of writing so may when otherwise i am looking for a more general solution in which i can define key value pairs and then call function and look for value for the input key. Is there something exist like this in xslt? – Anam Qureshi Feb 23 '21 at 04:41
  • You could put the key/value pairs in a variable or in an element (as was already suggested by Martin Honnen). However, there is no advantage in doing so - on the contrary, the code becomes more complicated and less efficient. – michael.hor257k Feb 23 '21 at 04:46
  • See the example here: https://stackoverflow.com/a/27998475/3016153 – michael.hor257k Feb 23 '21 at 05:03