我在這裏錯過了什麼?
我認爲一個人不應該搞亂XSLT處理器的默認縮進。
大多數情況下,<xsl:output indent="yes"/>
和<xsl:strip-space elements="*"/>
的組合足以獲得良好的縮進。
這種轉變:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="unit">
<unit>
<category1>
<xsl:apply-templates select="*[not(position() >2)]"/>
</category1>
<category2>
<xsl:apply-templates select="*[position() >2]"/>
</category2>
</unit>
</xsl:template>
</xsl:stylesheet>
時所提供的XML文檔應用:
<list>
<unit>
<data1>a</data1>
<data2>b</data2>
<data3>c</data3>
</unit>
</list>
可生產通緝,以及縮進結果:
<list>
<unit>
<category1>
<data1>a</data1>
<data2>b</data2>
</category1>
<category2>
<data3>c</data3>
</category2>
</unit>
</list>
當變換運行具有任何以下七個XSLT處理器的這種相同的結果將產生:
與MSXML3/4/6是更復雜的案例 - 這些XSLT處理器的壓痕由只是一個新行字符的,所以每一個元件是在一個新行,但出現在開始的線。
對於我使用以下兩個通處理這些XSLT處理器,第一遍是上述變換和所述第二應用到所述第一通過的結果one of the XML pretty-printers提出尼古萊·格里戈裏夫和可用在XSLT FAQ站點通過Dave Pawson維持:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="ext">
<xsl:output method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:param name="indent-increment" select="' '" />
<xsl:variable name="vrtfPass1">
<xsl:apply-templates select="/*"/>
</xsl:variable>
<xsl:variable name="vPass1" select="ext:node-set($vrtfPass1)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="$vPass1/*" mode="pass2"/>
</xsl:template>
<xsl:template match="unit">
<unit>
<category1>
<xsl:apply-templates select="*[not(position() >2)]"/>
</category1>
<category2>
<xsl:apply-templates select="*[position() >2]"/>
</category2>
</unit>
</xsl:template>
<xsl:template match="*" mode="pass2">
<xsl:param name="indent" select="'
'"/>
<xsl:value-of select="$indent"/>
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates mode="pass2">
<xsl:with-param name="indent"
select="concat($indent, $indent-increment)"/>
</xsl:apply-templates>
<xsl:value-of select="$indent"/>
</xsl:copy>
</xsl:template>
<xsl:template match="comment()|processing-instruction()" mode="pass2">
<xsl:copy />
</xsl:template>
<!-- WARNING: this is dangerous. Handle with care -->
<xsl:template match="text()[normalize-space(.)='']" mode="pass2"/>
</xsl:stylesheet>
當在相同的(提供的)XML文檔(上文)中進行這種轉化,所產生的結果具有所期望的縮進:
<?xml version="1.0" encoding="UTF-16"?>
<list>
<unit>
<category1>
<data1>a
</data1>
<data2>b
</data2>
</category1>
<category2>
<data3>c
</data3>
</category2>
</unit>
</list>
這些都是我在我的電腦上使用的XSLT處理器。我建議嘗試最後一次轉化 - 有可能會用Xalan-C產生想要的結果。
請注意:
最後轉換使用的MSXML - 特定的擴展功能XXX:節點集(),屬於一個MSXML - 特定的命名空間:
xmlns:ext="urn:schemas-microsoft-com:xslt"
對於Xalan的這需要與被替換:
xmlns:ext="http://exslt.org/common"
或者,如果不支持EXSLT,那麼本地的Xalan命名空間:
xmlns:ext="http://xml.apache.org/xalan
在最後這種情況下,到ext:node-set()
函數調用必須以ext:nodeset()
調用(注意沒有破折號)來代替:
<xsl:variable name="vPass1" select="ext:nodeset($vrtfPass1)"/>
你在找什麼?縮進? – 2012-07-05 18:42:57
是的。在輸出xml中縮進。 – owagh 2012-07-05 19:02:09
這是依賴於實現的。大多數處理器在使用'時一起或不使用'時產生良好的縮進。你在使用哪種XSLT處理器? –
2012-07-05 19:04:40