2

From what I understand having looked around for an answer to this the following should work:

<xslt basedir="..." destdir="..." style="xslt-stylesheet.xsd" extension=".xml"/>

Where xslt-stylesheet.xsd contains the following:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/">
        <xsl:copy-of select="."/>
    </xsl:template>
</xsl:stylesheet>

Unfortunately while most formatting is applied (spaces are stripped, newlines entered, etc.), indentation is not and every element is along the left side in the file. Is this an issue with the xslt processor Ant uses, or am I doing something wrong? (Using Ant 1.8.2).

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
Vala
  • 5,628
  • 1
  • 29
  • 55

4 Answers4

5

It might help to set some processor-specific output options, though you should note that these may vary depending on the XSLT processor that you're using.

For example, if you're using Xalan, it defines an indent-amount property, which seems to default to 0.

To override this property at runtime, you can declare xalan namespace in your stylesheet and override using the processor-specific attribute indent-amount in your output element as follows:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
              xmlns:xalan="http://xml.apache.org/xalan">

  <xsl:output method="xml" 
              encoding="UTF-8"
              indent="yes" 
              xalan:indent-amount="2"/>

This example is from the Xalan usage patterns documentation at http://xml.apache.org/xalan-j/usagepatterns.html

If you do happen to be using Xalan, the documentation also says you can change all of the output preferences globally by setting changing the file org/apache/serializer/output_xml.properties in the serializer jar.

In the interest of completeness, the complete set of Xalan-specific xml output properties defined in that file (Xalan 2.7.1) are:

{http://xml.apache.org/xalan}indent-amount=0
{http://xml.apache.org/xalan}content-handler=org.apache.xml.serializer.ToXMLStream
{http://xml.apache.org/xalan}entities=org/apache/xml/serializer/XMLEntities

If you're not using Xalan, you might have some luck looking for some processor-specific output properties in the documentation for your XSLT processor

Stewart Francis
  • 735
  • 5
  • 10
  • That's it. I don't understand why it would default the indent amount to 0, but that's fixed it. Thanks a lot! – Vala Jan 03 '12 at 10:33
1

Different XSLT processors implement indent="yes" in different way. Some indent properly, while others only put the element starting on a new line. It seems that your XSLT processor is among the latter group.

Why is this so?

The reason is that the W3C XSLT Specification allows significant leeway in what indentation could be produced:

"If the indent attribute has the value yes, then the xml output method may output whitespace in addition to the whitespace in the result tree (possibly based on whitespace stripped from either the source document or the stylesheet) in order to indent the result nicely; if the indent attribute has the value no, it should not output any additional whitespace. The default value is no. The xml output method should use an algorithm to output additional whitespace that ensures that the result if whitespace were to be stripped from the output using the process described in [3.4 Whitespace Stripping] with the set of whitespace-preserving elements consisting of just xsl:text would be the same when additional whitespace is output as when additional whitespace is not output.

NOTE:It is usually not safe to use indent="yes" with document types that include element types with mixed content."

Possible solutions:

  1. Start using another XSLT processor. For example, Saxon indents quite well.

  2. Remove the <xsl:strip-space elements="*"/> directive. If there are whitespace-only text nodes in the source XML, they would be copied to the output and this may result in a better-looking indented output.

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • Thanks for a thorough and likely useful answer. Unfortunately I can't currently use saxon (I don't have permission to grab jars we aren't currently using due to potential licensing issues), and the xml it's indenting has been stored in a property (which strips white space anyway), so removing the `strip-space` directive does nothing. :\ – Vala Dec 21 '11 at 15:32
  • I am sorry -- in this case you seem to be out of luck. AFAIK, Saxon 6 or Saxon 9 HE doesn't have any licensing implications (is free). Another free XSLT processor that appears to do good indentation is AltovaXML (XML-SPY). They all are easy to use even from the command line. If these cannot be used, you can try an available XML "pretty-printer". Search for "xml pretty-printer" and you'll find many such transformations. – Dimitre Novatchev Dec 21 '11 at 15:41
0

You can try adding the {http://xml.apache.org/xslt}indent-amount output property in ant, something like this:

<target name="applyXsl">
    <xslt in="${inputFile}" out="${outputFile}" extension=".html" style="${xslFile}" force="true">
        <outputproperty name="indent" value="yes"/>
        <outputproperty name="{http://xml.apache.org/xslt}indent-amount" value="4"/>
    </xslt>
</target>
Justin Rowe
  • 2,356
  • 1
  • 20
  • 15
0

I don't know if ant is OK. But concerning your XSLT :

When you use the copy-of on an element, your XSLT processor does not indent. If you change your XSLT like this, your XSLT processor will may be manage to indent :

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

This XSLT will go through the whole XML tree and indents each element it creates.

EDIT after comment :

You can see the following question to change your XSLT processor, maybe it will solve your problem : How to execute XSLT 2.0 with ant?

Community
  • 1
  • 1
Vincent Biragnet
  • 2,950
  • 15
  • 22
  • This statement isn't true. The whitespace-only nodes are stripped off at the very start of the XSLT transformation, before executing other instructions. The XSLT 1.0 Spec says: "After the tree for a source document or stylesheet document has been constructed, but before it is otherwise processed by XSLT, some text nodes are stripped." See at: http://www.w3.org/TR/1999/REC-xslt-19991116#strip – Dimitre Novatchev Dec 21 '11 at 13:15
  • @Dimitre. Thanks for pointing this. That's right, as you said, the problem comes maybe from the processor but, the XSLT should correct this. I change my answer. – Vincent Biragnet Dec 21 '11 at 13:16
  • Unfortunately this stylesheet has exactly the same effect as the one in my question. – Vala Dec 21 '11 at 15:23