代码之家  ›  专栏  ›  技术社区  ›  Andrew Swan

如何防止XSLT换行?

  •  4
  • Andrew Swan  · 技术社区  · 14 年前

    我有一些这样的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>
    

    我想通过文本表示对“sortable”元素的子元素进行排序,以得到以下结果:

    <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"/>
    
    1 回复  |  直到 14 年前
        1
  •  4
  •   Dimitre Novatchev    14 年前

    我如何保持所有这些属性 同一条线

    在代码中,替换 :

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

    具有

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

    当然,这将在一条线上产生完整的输出!在编写这个XSLT2.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>
    

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

    <根& gt;
    <不排序>
    <Z></Z>
    <Y></Y>
    </不排序>
    <可排序>
    <this is=“an”element=“with”a=“lot”of=“attributes”and=“the”excess=“ones”each=“wrap”on=“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>
    &根/根;