0

I have an XML and I would like to change the attribute value (name="name") to another one (name="value") with following xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!--xsl:template match="text()"-->
<!--xsl:text select="." disable-output-escaping="yes" /-->
<!--xsl:value-of select="." disable-output-escaping="yes" />
   <xsl:copy-of select="child::*"/> 
  </xsl:template-->

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

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

<xsl:template match="@name" mode="se">
    <xsl:attribute name="name">value</xsl:attribute>
</xsl:template>
<xsl:template match="tag5[@type='testtype']">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" mode="s"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="tag6[@name='name']" mode="s">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" mode="se"/>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

XML INPUT snippet:

<?xml version="1.0" encoding="UTF-8"?>
<dataroot version="2.0">
<Model id="111" name="test">
    <tag1 id="222" type="VERSION">
        <tag2 id="333" name="Version" value="2"/>
    </tag1>
    <tag3 id="444">
        <tag4 id="555" versionID="test/00001" name="name" definition="through test. &#xD;&#xA;" attrs="12 23"/>
        <tag4 id="666" versionID="test/00001" name="name" definition="through test 2. &#xD;&#xA;" messages="34 45"/>
    </tag3>
    <tag5 id="777" type="testtype">
        <tag6 id="888" name="name" value="667"/>
        <tag6 id="999" name="context" value="FIX 5.0"/>
    </tag5>
</Model>
</dataroot>

The XML OUTPUT after applying xslt is:

<?xml version="1.0" encoding="UTF-8"?>
<dataroot version="2.0">
<Model id="111" name="test">
    <tag1 id="222" type="VERSION">
        <tag2 id="333" name="Version" value="2"/>
    </tag1>
    <tag3 id="444">
        <tag4 id="555" versionID="test/00001" name="name" definition="through test. &#13;&#10;" attrs="12 23"/>
        <tag4 id="666" versionID="test/00001" name="name" definition="through test 2. &#13;&#10;" messages="34 45"/>
    </tag3>
    <tag5 id="777" type="testtype">
        <tag6 id="888" name="value" value="667"/>
        <tag6 id="999" name="context" value="FIX 5.0"/>
    </tag5>
</Model>
</dataroot>

The xslt basically does what it is expected to do. However, with unexpected transform:

&#xD;&#xA;   ->   &#13;&#10;   (unexpected transform)

I want to preserve the original entities. I have tried the disable-output-escape (see the commented section in xslt with chaging text to @definition), doesn't work. Any suggestions?

I use xsltproc btw.

Thanks in advance!

dellair
  • 427
  • 4
  • 22
  • You can't preserve character references with XSLT, the XSLT processor uses an XML parser to parse the input intro a tree of nodes with values of Unicode characters and then works with Unicode characters. The transformation result is then serialized where any necessary escaping is done. So you can't solve that with pure XSLT, you would need to look at your particular XSLT processor and its serialization features whether you can enforce the use of hexadecimal character references. – Martin Honnen Mar 25 '16 at 14:14
  • @MartinHonnen, I use xsltproc, any tips? – dellair Mar 25 '16 at 14:29
  • @dellair What difference does it make? Both ` ` and ` ` are [equally valid representation of the same character.](https://www.w3.org/TR/REC-xml/#dt-charref) Why would you care about this? – michael.hor257k Mar 25 '16 at 14:31
  • @michael.hor257k, The XML file is a model which is the source of many other tools. Hence each attributes are handled by different and multiple tools. I want to minimize the change to avoid surprises. – dellair Mar 25 '16 at 14:35
  • Any tool that conforms to the XML standard should be able to handle both representations equally. In any case, you cannot preserve the original representation (as already explained by Martin Honnen), you can only force one type of representation or another. It's possible to do that in XSLT 1.0 self, by replacing the characters with escaped strings (e.g. `&#xA;`) and outputting these with DOE - but it is a lot of work. – michael.hor257k Mar 25 '16 at 14:54
  • @michael.hor257k, thanks, I will use perl to process it. – dellair Mar 25 '16 at 15:42

1 Answers1

0

It seems that xslt is not able to handle this requirement, so I did it in perl. Thanks all!

dellair
  • 427
  • 4
  • 22
  • "*xslt is not able to handle this requirement*" That's not what I said. – michael.hor257k Mar 25 '16 at 15:44
  • Your Perl program almost certainly introduces a dependency on the precise way that the input document is represented. It's because people insist on writing such programs, rather than using a real XML parser, that you end up with the difficulty you started with: you can't generate arbitrary XML, you have to generate some XML subset/dialect, because someone has written an application at the receiving end that isn't parsing XML properly. So you end up with a vicious cycle in which you are exchanging data using a proprietary syntax, and losing all the benefits that come from standard XML. – Michael Kay Mar 25 '16 at 18:26
  • @michael.hor257k, sorry I might have misunderstood. But I couldn't easily find a solution for this requirement. – dellair Mar 26 '16 at 11:33
  • @MichaelKay, your comment is valid, but sometimes we want to be flexible on using technology for different purpose. In this case, I use an alternative to meet the needs simply because I wasn't able to do it via xslt. Please feel free to post your answer and I will happily accept it. – dellair Mar 26 '16 at 11:35
  • You can't do what you want to do with XSLT because what you want to do is bad practice. – Michael Kay Mar 26 '16 at 12:39
  • 1
    @dellair I outlined a possible solution in my comment above. I am not going to elaborate, because (1) as I said, it's a lot of work and (2) I don't think it should be necessary. -- P.S. Could you not test the target applications with the "new" format? You might be trying to solve a problem that doesn't exist (and certainly should not exist). – michael.hor257k Mar 26 '16 at 16:20
  • Kay, You need to understand that there are industries using combination of xml and other tools on top of it. In a ideal world, it is one technology solving all the issues. But this isn't in the case. And migration is neither trivial nor a simple word. I understand people see things from different perspective. Will close the conversation as for now. Thanks for showing interest. – dellair Mar 26 '16 at 21:10