0

In this scenario I receive an XML document with an unknown amount of nodes in which special characters (e.g. "&") have been changedto their unicode characters (e.g. __u0026), like this:

<result>
<reference_list>
    <department1>123</department1>
    <department2>456</department2>
    <DepX__u0020__u0026__u0020DepY>789</DepX__u0020__u0026__u0020DepY>

What I want to do is transform this XML so that the nodes become values of nodes in the target document and then hoover over the entire document to replace the unicode characters with their actual signs (e.g. change u0026 back to &).

The result should look like this:

    <ns2:reference_list>
    <ns2:department>
        <ns2:name>department1</ns2:name>>
        <ns2:id>123</ns2:id>
    </ns2:department>
    <ns2:department>
        <ns2:name>department2</name>
        <ns2:id>456</ns2:id>
    </ns2:department>
    <ns2:department>
        <ns2:name>DepX & DepY/></name>
        <ns2:id>789</ns2:id>
    </ns2:department>

I can manage to do the first step (get the result XML without changing the unicode characters back to their original signs) but I don't know how to ALSO get the second step done (i.e. get " & " instead of "__u0020__u0026__u0020").

I've tried various suggestions found on this forum, but none of them seemed readily applicable to my situation. My current situation:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns2="namespace/url">
<xsl:key name="elements" match="*" use="name()"/>

<xsl:param name="pTarget" select="'__u0026'" />
<xsl:param name="pReplace" select="'&'"/>

<xsl:template match="/">
    

    <ns2:result>
        <ns2:reference_list>
            <xsl:for-each select="result/reference_list/*[generate-id(.)=generate-id(key('elements',name())[1])]">
                <xsl:sort select="name()"/>
                <xsl:for-each select="key('elements', name())">
                
                    <xsl:if test="position()=1">
                    <ns2:department>
                        <ns2:name>
                            <xsl:variable name="ampersand" select="concat(name(), $pTarget)"/>
                            <xsl:value-of select="{substring-before($ampersand,$pTarget)}{$pReplace}{substring-after(name(),$pTarget)}"/>
                        </ns2:name>
                        <ns2:id>
                            <xsl:value-of select="current()"/>
                        </ns2:id>
                    </ns2:department>
                    </xsl:if>
                </xsl:for-each>
            </xsl:for-each>
        </ns2:reference_list>
    </ns2:result>

</xsl:template>

Other suggestions I have tried that I figured were most promising:

Update the text of an element with XSLT based on param

How to concat a string to xsl:value-of select="...?

XSLT string replace

Reinout
  • 1
  • 1
  • Are you restricted to XSLT 1.0? If so, which XSLT processor exactly do you use? What are the rules to decide when to transform an element to `ns2:department`, is that based on the existence of `__` in the element name? Why is that grouping attempt in the XSLT code although the input sample and the result show no sign or need of grouping? – Martin Honnen Nov 04 '21 at 16:27
  • You say the result should include `DepX & DepY/>` but that wouldn't be well-formed XML. The `&` must be escaped as `&`. – Michael Kay Nov 04 '21 at 17:52
  • Converting hex codes like 0026 to the corresponding Unicode characters is almost impossible in pure XSLT 1.0; it becomes much more feasible in 2.0. – Michael Kay Nov 04 '21 at 17:54
  • Unless you have a list of all codes that can appear in the input (or at least a range of characters), this is not possible in pure XSLT 1.0. But some processors can dip into other languages where this feature exists. – michael.hor257k Nov 04 '21 at 18:13

0 Answers0