-1

I have a xslt stylesheet to process some XML data, provided by a legacy system. XML Sample:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<contract>
    <variable id="info">
        <variable id="client">
            <variable id="profession" value="0128"/>
            <variable id="missingInfo" value="null"/>
            <variable id="address">
                <variable id="town" value="MADRID"/>
                <variable id="street" value="CALLE SAN SEBASTIAN"/>
                <variable id="postalCode" value="50505-207"/>
            </variable>
            <variable id="taxId" value="123456789"/>
            <variable id="declineDetails" value="null"/>
        </variable>
        <variable id="height" value="null"/>
    </variable>
    <variable id="supplier">
        <variable id="phoneNumber" value="1020304050"/>
        <variable id="address">
            <variable id="town" value="BARCELONA"/>
            <variable id="street" value="AVINGUDA DIAGONAL 44"/>
            <variable id="postalCode" value="40780-575"/>
        </variable>
        <variable id="taxId" value="1020304050"/>
        <variable id="name" value="STICKS &amp; STONES"/>
        <variable id="birthDate" value="null"/>
        <variable id="email" value="sticksandstones@beemail.org"/>
    </variable> 
</contract>

XSL stylesheet in use (simplified):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <result>
            <xsl:for-each select="/contract/variable[@id = 'info']/variable[@id = 'client' and variable[@id = 'taxId']/@value != ../variable[@id = 'supplier']/variable[@id = 'taxId']/@value]">
                <xsl:variable name="taxId" select="variable[@id = 'taxId']/@value"/>
                <contract>
                    <variable id="info">
                        <xsl:copy-of select="/contract/variable[@id = 'info']/variable[@id = 'client' and variable[@id = 'taxId']/@value = $taxId]"/>
                        <xsl:copy-of select="/contract/variable[@id = 'info']/variable[@id != 'client']"/>
                    </variable>
                    <xsl:copy-of select="/contract/variable[@id != 'info']"/>
                </contract>
            </xsl:for-each>
        </result>
    </xsl:template>
</xsl:stylesheet>

When the stylesheet is applied, there's an exception:

Caused by: net.sf.saxon.trans.XPathException: No closing ';' found for entity or character reference

I tried to process the same data, changing %&mp; to a letter (let's say E), everything works as expected. Example:

<variable id="name" value="STICKS E STONES"/>

I also tried to use disable-output-escaping, but without luck, as it seems that is only compatible with xsl:value-of instructions, and not xsl:copy-of instructions.

All the transformations without the ampersand sign work as expected.

What I'm trying to achieve:

<variable id="name" value="STICKS &amp; STONES"/>

How can I keep the ampersand in the final transformed xml?

noitib
  • 148
  • 1
  • 13

1 Answers1

1

You haven't provided the part of the code that is responsible for the error.

There are strange things about your code: it does both /data/variable and /contract/variable without changing the context item: surely the outermost element is either data or contract, it can hardly be both. In addition, you have a xsl:for-each which processes some set of nodes, and the action it performs is exactly the same regardless which node you are processing.

So there's a lot wrong with your code, but nothing that directly explains the error you are reporting.

You ask "How can I keep the ampersand in the final transformed xml?" but you don't actually tell us what output you are trying to produce.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • Seems like I made things more complex than needed, by trying to simplify the examples provided. I edited both the XML sample and the xslt sample, and clearly identified the expected outout. Thanks for taking the time to look into my answer and providing tips on how to improve it. – noitib May 27 '20 at 08:46
  • I'm rather mystified by this. There's nothing obviously wrong in the code you've shown us. The message `No closing ';' found for entity or character reference` doesn't originate from Saxon; Saxon must be passing it on from somewhere else, most probably an XML parser. The "Caused by" in the message suggests this message is part of a stack trace; it might be useful to have the full stack trace. – Michael Kay May 27 '20 at 10:14
  • You are absolutely right. After being processed by the xslt, the data is processed by a framework to generate a fixed-position file. That is, indeed where the error occurs. Sorry for wasting time, and thanks again for taking the time to help. – noitib May 27 '20 at 10:47