0

I have HTML in XML format which I am parsing using XSLT. My HTML looks like this:

<html>
<head>
<meta charset="utf-8" />
<title>Test</title>
</head>
<body>
<img height=""  width="' src="google.gif?<>" />
</body>
</html>

After XSLT parsing it looks like this:

 <html>
    <head>
    <meta charset="utf-8" />
    <title>Test</title>
    </head>
    <body>
    <img height="" src="google.gif?<>" width=""/>
    </body>
    </html>

I want @src as last attribute like <img height="" width="" src="google.gif?<>" />, but by default attributes are sorted in alphabetical order. I am not able to do it using <xsl:sort>.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • 1
    I am afraid `" />` is not well-formed XML at all. And of course we would need to see your XSLT as well that allegedly reorders the attributes. – Martin Honnen Aug 30 '16 at 12:54
  • 1
    Moreover, [attribute order is insignificant per the XML Recommendation](http://stackoverflow.com/a/39228435/290085). – kjhughes Aug 30 '16 at 13:18

3 Answers3

1

Input HTML (with wellformation):

<html>
<head>
    <meta charset="utf-8" />
    <title>Test</title>
</head>
    <body>
        <img height="13" width="12" src="google.gif?" id="id1"/>
    </body>
</html>

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

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

<xsl:template match="img">
    <xsl:copy>
        <xsl:for-each select="@*[not(name()='src')]">
            <xsl:sort select="name()"/>
            <xsl:attribute name="{name()}">
                <xsl:value-of select="."/>
            </xsl:attribute>
        </xsl:for-each>
        <xsl:apply-templates select="@*[name()='src']"/>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Result:

<html>
<head>
  <meta charset="utf-8"/>
  <title>Test</title>
</head>
<body>
  <img height="13" id="id1" width="12" src="google.gif?"/>
</body>
</html>
Rudramuni TP
  • 1,268
  • 2
  • 16
  • 26
  • Hi, I want the result as Test I always wants @src in the last. – user3287034 Aug 30 '16 at 17:36
  • @user3287034, edited my answer, as required, as kjhughes suggestion, attributes can be any order, but only when some other scripting languages (which are not supporting xpath) are accessing or processing the input xml, for the find replace process at that time these position of attribute may be helpful. – Rudramuni TP Aug 31 '16 at 05:50
1

XSLT produces as output a result tree conforming to the XDM data model, and in the XDM model, attributes are unordered. Since they have no order, it follows that XSLT stylesheet instructions cannot control the order.

The only opportunity for controlling the order arises during serialization, when the unordered attribute nodes in the result tree are converted to an ordered sequence of name="value" pairs in the lexical XML output. The standard serialization properties available in XSLT (any version) do not provide any way of controlling this. Saxon however has an extension attribute saxon:attribute-order - see

http://www.saxonica.com/documentation/index.html#!extensions/output-extras/serialization-parameters

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
0

In addition to <img height="" width="' src="google.gif?<>" /> not being well-formed as commented by Martin Honnen...

Attribute order is insignificant per the XML Recommendation:

Note that the order of attribute specifications in a start-tag or empty-element tag is not significant.

Therefore, XSLT provides no way to constrain attribute ordering.

If you refuse to embrace this recommendation to ignore ordering for attributes, see Martin Honnen's suggestions regarding how to control attribute ordering output to an earlier question on XSLT attribute ordering.

Community
  • 1
  • 1
kjhughes
  • 106,133
  • 27
  • 181
  • 240