如何通过XSLT防止换行?

时间:2010-07-15 01:23:57

标签: xslt

我有一些像这样的XML:

<root>
   <do-not-sort>
      <z/>
      <y/>
   </do-not-sort>
   <sortable>
      <e f="fog" h="bat" j="cat">
          <n n="p"/>
          <m n="p"/>
      </e>
      <d b="fop" c="bar" k="cab">
          <m o="p"/>
          <m n="p"/>
      </d>
   </sortable>
</root>

我想通过文本表示对“可排序”元素的子项进行排序,最后得出结论:

<root>
   <do-not-sort>
      <z/>
      <y/>
   </do-not-sort>
   <sortable>
      <d b="fop" c="bar" k="cab">
          <m n="p"/>
          <m o="p"/>
      </d>
      <e f="fog" h="bat" j="cat">
          <m n="p"/>
          <n n="p"/>
      </e>
   </sortable>
</root>

我目前正在通过应用以下XSLT模板来执行此操作:

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

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

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

  <xsl:template match="*">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:value-of select="normalize-space(text()[1])" />
      <xsl:apply-templates select="*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="sortable//*">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:value-of select="normalize-space(text()[1])" />
      <xsl:apply-templates select="*">
        <xsl:sort data-type="text" select="local-name()" />
        <xsl:sort data-type="text" select="@*" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

排序工作正常,但如果排序的元素有很多属性,则后面的属性每个都会换行到一个新行,例如:

<sortable>
    <this is="an" element="with" a="lot" of="attributes"
            and="the"
            excess="ones"
            each="wrap"
            onto="their"
            own="line"/>

如何将所有这些属性保留在同一行,即

<sortable>
    <this is="an" element="with" a="lot" of="attributes" and="the" excess="ones" each="wrap" onto="their" own="line"/>

2 个答案:

答案 0 :(得分:4)

  

如何保留所有这些属性   同一行

在您的代码中,替换

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

<强>与

  <xsl:output method="xml" encoding="UTF-8" /> 

当然,这将在一条线上产生完整的输出!在撰写本文时,XSLT 2.0仍然没有对输出的序列化进行更精细的控制。

如果你需要一些缩进的元素而某些元素没有缩进,那么你将不得不提供自己的后期处理(这种后处理可能更容易用不同的XSLT编写)。

<强>更新

实际上,使用Saxon 9.1.07和

  <xsl:output method="html" encoding="UTF-8" />

完整的转换是:

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="html" encoding="UTF-8" />

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

  <xsl:template match="*">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:value-of select="normalize-space(text()[1])" />
      <xsl:apply-templates select="*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="sortable//*">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:value-of select="normalize-space(text()[1])" />
      <xsl:apply-templates select="*">
        <xsl:sort data-type="text" select="local-name()" />
        <xsl:sort data-type="text" select="@*" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

,源XML文档是:

<root>
   <do-not-sort>
      <z></z>
      <y></y>
   </do-not-sort>
   <sortable>
      <this is="an" element="with" a="lot" of="attributes" and="the" excess="ones" each="wrap" onto="their" own="line"></this>
      <e f="fog" h="bat" j="cat"></e>
      <d b="fop" c="bar" k="cab"></d>
      <d b="foo" c="baz" k="cap"></d>
   </sortable>
</root>

我得到了想要缩进的输出:

<root>
   <do-not-sort>
      <z></z>
      <y></y>
   </do-not-sort>
   <sortable>
      <this is="an" element="with" a="lot" of="attributes" and="the" excess="ones" each="wrap" onto="their" own="line"></this>
      <e f="fog" h="bat" j="cat"></e>
      <d b="fop" c="bar" k="cab"></d>
      <d b="foo" c="baz" k="cap"></d>
   </sortable>
</root>

答案 1 :(得分:0)

如果您正在使用Saxon,并且希望避免所有内容都在一行上,则可以使用'line-length'属性,如下所示:

<xsl:output xmlns:saxon="http://saxon.sf.net/" indent="yes" saxon:line-length="2000"/

但是,请注意,这仅适用于Saxon PE(专业)版。详细信息请参见此处: http://www.saxonica.com/products/products.xml

如果您使用的是HE(家庭版),则会出现如下错误:

转换失败:请求的功能(自定义序列化{http://saxon.sf.net/}行长)需要Saxon-PE