1
votes

With xsltproc (XSLT 1.0) I'm trying to escape (" -> to \") content from xsl-value @name attribute.

XSL:

<xsl:template match="int:signature">
    "name":"<xsl:value-of select="@name" mode="text"/>",
    ....

Original XML:

<signature name="My &quot;case&quot;" />

Output:

 "name":"My "case"",

which breaks resulting JSON

I've tried using str:replace with no success. No success with disable-output-escaping="yes" either.

Any hint?

--

xsltproc -V

Using libxml 20706, libxslt 10126 and libexslt 815

2
Please add an example with your expected output (and perhaps input): shout this be "name":"xxxxx" or \"name":\"xxxxx\". Or should the content of @name be changed? โ€“ hr_117
I've improved explanation a bit. Yes, content of @name should be changed (to be escaped). โ€“ Toni Hermoso Pulido
One possibility with xslt 1.0 would be to use recursive template calls to escape the quotes. But would it not be sufficient to change the outward quot to an apostrophe. "name":My "case"ยด,` (This should be valid jason) โ€“ hr_117

2 Answers

0
votes

This works with XPath 2.0

"name":"<xsl:value-of select='fn:replace(@name, """", "\\""")' />"

xsltproc doesn't support Xpath 2.0 as far as I know, but maybe the EXSLT extensions provide the same functionality

0
votes

If your need to escape something like this will help

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space  elements="*"/>
    <xsl:template match ="signature">
        <xsl:variable name="escape">
            <xsl:call-template name="escape_quot">
                <xsl:with-param name="replace" select="@name"/>
            </xsl:call-template>
        </xsl:variable>
        "name":"<xsl:value-of select="$escape" />",
    </xsl:template>

    <xsl:template name="escape_quot">
        <xsl:param name="replace"/>
        <xsl:choose>
            <xsl:when test="contains($replace,'&quot;')">
                <xsl:value-of select="substring-before($replace,'&quot;')"/>
                <!-- escape quot-->
                <xsl:text>\"</xsl:text> 
                <xsl:call-template name="escape_quot">
                    <xsl:with-param name="replace" select="substring-after($replace,'&quot;')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$replace"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

This will generate the wonted output.

 "name":"My \"case\"",

Update:
But would it not be sufficient to change the outward quot to an apostrophe.

with:

 "name":'<xsl:value-of select="@name" />',

to get:

  "name":'My "case"',

(This should be valid JSON)