我正在使用xalan和以下xsl标头:
<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"/>
输出没有缩进。
有想法的人吗?
答案 0 :(得分: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"/>
答案 1 :(得分:9)
暂时挣扎了一段时间,但是让它意外地工作了:
关键是要添加<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="*"/>
不确定原因,但可能删除所有whitespacing有助于xalan找出缩进
答案 2 :(得分:5)
Jirka-x1,谢谢你的问题链接。我使用了以下内容(由Ed Knoll 13 / Aug / 04提出):
<xsl:stylesheet ... xmlns:xslt="http://xml.apache.org/xslt">
<xsl:output ... indent="yes" xslt:indent-amount="4" />
这适用于xalan(java)2.7.1。
答案 3 :(得分: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"/>
答案 4 :(得分:0)
虽然这是一个很老的问题,但答案上可能还有另一个尚未涉及的角度。
TL; DR与Result
注入的Transformer
的味道很重要。(如果您通过Java代码使用xalan,则不会编写/可以没变化,这可能不是您想听到的。)
对于此答案中的演示,我将使用PostgreSQL PL / Java,因为它附带了一组示例函数,包括preparexmltransform
和transformxml
,这些函数使用Java的基于xalan的XSLT 1.0,并有一些额外的参数用于测试目的。没有这些额外的参数,我不会看到一个重要的行为影响。
我将从准备一个名为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);
应该足够清楚,第一个参数是转换的名称,第二个参数是定义转换的XSLT。我将稍后讨论“如何”的论点。
因此,无论如何,让我们在某些XML上使用该转换,看看会发生什么:
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
属性(除非您喜欢不同的缩进宽度),因此它不需要定义xalan
命名空间,也不必{{{ 1}}元素可以正常工作(如果您尝试在输入文档中使用空格,则仅向其中添加缩进空格,看起来有些愚蠢,因此您可能选择以使用{{1} },但缩进会以任何一种方式发生。
我还没有说这些额外的参数做什么(现在是它们中的两个,“ 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,SQLXML API必须为您提供使用这些数据的任何方式的选择,以您方便的方式为准任务。而且JAXP Transformations API指出,您必须能够将InputStream
和OutputStream
的任何口味的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>
,Transformer
或SAXResult
进行写入时,它不会添加缩进,因为它们都是结构化XML API。好像xalan严格将缩进视为序列化问题,并且在生产SAX,StAX或DOM时,从技术上讲,它不是序列化。
(上表还显示,当其他API进行操作时,StAX API并不总是将空元素呈现为自关闭状态。附带问题,但很有趣。)
因此,如果您发现自己试图进行xalan转换以进行缩进,但并非如此,请仔细检查您要求StAXResult
产生哪种形式的DOMResult
。
编辑:最后一点:如果您直接用Java编写代码,那么实际上根本不需要编写XSLT的那七行代码,仅仅是为了得到什么而已。设置了Result
输出属性的身份转换。
如果您调用无参数TransformerFactory.newTransformer()
,它会直接给您 一个普通的身份转换。然后,您需要做的就是设置其输出属性,然后您就可以从事业务:
Transformer
没有比这更简单的了。同样,将indent
设为var tf = javax.xml.transform.TransformerFactory.newInstance();
var t = tf.newTransformer();
t.setOutputProperty("indent", "yes");
t.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "1"); // if you don't like the default 4
t.transform(source, result);
至关重要,这样转换器才能进行序列化。