我如何使xsl转换使输出缩进?

问题描述 投票:11回答:5

我正在使用带有以下xsl标头的xalan:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"
    xmlns:redirect="http://xml.apache.org/xalan/redirect"
    extension-element-prefixes="redirect"
    xmlns:xalan="http://xml.apache.org/xalan">
<xsl:output method="text" indent="yes" xalan:indent-amount="4"/>

并且输出不缩进。

有人有想法吗?

xslt indentation xalan
5个回答
21
投票

对于缩进,您需要使用其他名称空间:“ http://xml.apache.org/xslt”(请参阅​​this issue

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:redirect="http://xml.apache.org/xalan/redirect"
extension-element-prefixes="redirect"
xmlns:xalan="http://xml.apache.org/xslt">
<xsl:output method="xml" indent="yes" xalan:indent-amount="4"/>

10
投票

曾为此苦苦挣扎了一段时间,但只是意外地使它起作用:

关键是要添加<xsl:strip-space elements="*"/>

所以它看起来像这样:

<xsl:stylesheet 
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:java="http://xml.apache.org/xalan/java"
    xmlns:xalan="http://xml.apache.org/xslt">
<xsl:output method="xml" encoding="ASCII" indent="yes" xalan:indent-amount="4"/>
<xsl:strip-space elements="*"/>

不知道为什么,但是可能删除所有空格以帮助xalan找出缩进


5
投票

Jirka-x1,谢谢您的问题链接。我使用了以下内容(由Ed Knoll提议,04年8月13日):

<xsl:stylesheet ... xmlns:xslt="http://xml.apache.org/xslt">
<xsl:output ... indent="yes" xslt:indent-amount="4" />

这对我来说适用于xalan(java)2.7.1。


2
投票

我想您必须将method设置为xml。如果那不起作用,请尝试以下操作:

<?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="4"/>

0
投票

虽然这是一个非常老的问题,但答案上可能还有一个尚未涉及的角度。

TL; DR至关重要,Result馈入的是Transformer的味道。(如果您通过Java代码使用xalan,则您没有编写/无法更改,这可能不是您想听到什么。)

对于此答案中的演示,我将使用PostgreSQL PL / Java,因为它附带了一组示例函数,包括preparexmltransformpreparexmltransform,它们使用Java的基于xalan的XSLT 1.0东西,并具有一些额外的参数。用于测试目的。没有这些额外的参数,我不会看到一个重要的行为影响。

我将从准备一个名为transformxml的转换开始:

transformxml

应该足够清楚,第一个参数是转换的名称,第二个参数是定义转换的名称。我将稍等一下“ how”参数。

所以无论如何,让我们在XML上使用该转换,看看会发生什么:

indent

很酷,马上就完成了想要的工作,并表明上面的简短转换就足够了;值得注意的是,它不需要SELECT preparexmltransform( 'indent', '<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <xsl:copy-of select="."/> </xsl:template> </xsl:transform>', how => 5); 属性(除非您希望使用不同的缩进宽度),因此它不需要定义SELECT transformxml( 'indent', '<a b="c" d="e"><f><g/><h/></f></a>', howin => 5, howout => 4); transformxml ---------------- <a b="c" d="e"> <f> <g/> <h/> </f> </a> 命名空间,也不必为此提供xalan:indent-amount元素可以正常工作(如果您尝试在输入文档中使用空格,则仅向其中添加缩进空格,这看起来很愚蠢,因此您可能choose使用xalan,但是缩进会以任何一种方式发生。) >

我仍然没有说这些额外的参数做什么(现在是它们的两个,“ howin”和“ howout”!),但这是即将到来的,因为看起来除了“ howout”从4变为5之外什么都没有发生。] >

strip-space

因此,“缩进”对于缩进是否发生很重要。这些方法是什么?

嗯,Java并不只有一个用于处理XML的API。它有多个,包括DOM,StAX和SAX,更不用说您可能只想将XML处理为strip-space,通过SELECT transformxml( 'indent', '<a b="c" d="e"><f><g/><h/></f></a>', howin => 5, howout => 5); transformxml ------------------------------------ <a b="c" d="e"><f><g/><h/></f></a> / String的字符流或通过Reader的编码字节流。 ] / Writer

JDBC规范说,如果您正在编写Java代码以在数据库中使用XML,则InputStream必须为您提供使用这些数据的任何方式的选择,以您方便的方式为准。 JAXP Transformations API说,您必须能够处理几乎所有OutputStreamSQLXML API风格的Transformer,并使其正确执行操作。

所以这就是那些PL / Java示例函数具有“如何”参数的原因:需要一种方法来测试将相同XML内容可以传递给Source的所有必需方式,以及Result的所有方式。的结果可以回来。 “方式”是这样(任意)排列的:

Transformer

那么,用不同的方式产生结果时,相同的xalan缩进转换会做什么?

Transformer

嗯,有模式。对于所有 code | form | howin | howout ------+---------------------+--------------+-------------- 1 | binary stream | InputStream | OutputStream 2 | character stream | Reader | Writer 3 | String | String | String 4 | binary or character | StreamSource | StreamResult 5 | SAX | SAXSource | SAXResult 6 | StAX | StAXSource | StAXResult 7 | DOM | DOMSource | DOMResult 实际上必须直接产生序列化的字符或字节流

的API,它会按要求添加缩进。

当给定要写入的SELECT i, transformxml( 'indent', '<a b="c" d="e"><f><g/><h/></f></a>', howin => 5, howout => i) FROM generate_series(1,7) AS i; i | transformxml ---+------------------------------------------ 1 | <a b="c" d="e"> | <f> | <g/> | <h/> | </f> | </a> | 2 | <a b="c" d="e"> | <f> | <g/> | <h/> | </f> | </a> | 3 | <a b="c" d="e"> | <f> | <g/> | <h/> | </f> | </a> | 4 | <a b="c" d="e"> | <f> | <g/> | <h/> | </f> | </a> | 5 | <a b="c" d="e"><f><g/><h/></f></a> 6 | <a b="c" d="e"><f><g></g><h></h></f></a> 7 | <a b="c" d="e"><f><g/><h/></f></a> TransformerSAXResult时,它不会添加缩进,因为它们都是结构化XML API;好像xalan严格将缩进视为序列化问题,并且在生成SAX,StAX或DOM时,它技术上未序列化

((上表还显示,当其他API进行操作时,StAX API并不总是将空元素呈现为自关闭状态。附带问题,但很有趣。)

因此,如果您发现自己试图进行xalan转换以进行缩进,但并非如此,请仔细检查您要生成StAXResult的哪种形式。

© www.soinside.com 2019 - 2024. All rights reserved.