XSL FO在现有排序/条件XSL上的内联对齐

时间:2011-01-20 18:29:55

标签: xslt xsl-fo

我需要在同一行中进行右对齐和左对齐。查看类似的回复,我找到了以下建议,

<fo:block text-align-last="justify">
  LEFT TEXT (want this to be the Contacts element from the below)
  <fo:leader leader-pattern="space" />
  RIGHT TEXT (want this to be the Address1 element from the below)
</fo:block>

但是当我尝试将它应用到我现有的XSL代码(见下文)时,我无法使其工作 - 我不知道如何编辑它以适应/合并排序/条件和FO 。有人可以帮助我做到这一点吗?

现有/工作代码:

<?xml version="1.0"?><!-- DWXMLSource="XML - Builder Members.xml" -->
<!DOCTYPE xsl:stylesheet  [<!ENTITY nbsp   "&#160;">]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="no"/>

  <xsl:template match="/">
    <memberdata>  
      <xsl:for-each select="memberdata/memberinfo">
        <xsl:sort select="SortKey"/>
        <memberdata>
          <xsl:if test="Contacts[.!='']">
            <Contacts><xsl:value-of select="Contacts" /></Contacts>
            <xsl:text>&#10;</xsl:text>
          </xsl:if>
          <xsl:if test="Address1[.!='']">
            <Address1><xsl:value-of select="Address1" /></Address1>
            <xsl:text>&#10;</xsl:text>
          </xsl:if>
        </memberdata>
      </xsl:for-each>
    </memberdata> 
  </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:0)

独立于您的问题的实际答案(目前的形式无法提供问题),我想建议您对XSLT的一般方法进行一些改进:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="no"/>

  <xsl:template match="memberdata">
    <xsl:copy>
      <xsl:apply-templates select="memberinfo">
        <xsl:sort select="SortKey" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="memberinfo">
    <memberdata>
      <xsl:apply-templates select="Contacts" />
      <xsl:apply-templates select="Address1" />
    </memberdata>
  </xsl:template>

  <xsl:template match="Contacts|Address1">
    <xsl:if test="normalize-space() != ''">
      <xsl:copy-of select="." />
      <xsl:text>&#10;</xsl:text>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>
  • 避免使用<xsl:for-each>,使用不同的模板和<xsl:apply-templates>。这样可以实现更清晰,更少重复和更少嵌套的代码。它还可以更有效地处理样式表,因为XSLT处理器针对模板匹配进行了优化,并且可以并行化模板执行。
  • 请注意,您可以对多个元素使用相同的模板,请参阅上面的第三个模板。
  • 避免通过这样的构造添加换行符:<xsl:text>
    </xsl:text>
    。这样做会破坏源代码的可读性,并且在源代码格式化后很容易出错(我已经在您的问题中完成了这一点,以便能够首先正确地缩进代码)。使用字符引用&#10;来分隔源代码布局和输出布局。
  • 请注意,您可以使用<xsl:copy-of>制作元素的副本,而无需执行<foo><xsl:value-of select="foo" /></foo>

答案 1 :(得分:0)

以面值表达你的请求,这似乎是你所要求的,它将排序,条件和FO合并。

<?xml version="1.0"?><!-- DWXMLSource="XML - Builder Members.xml" -->
<!DOCTYPE xsl:stylesheet  [<!ENTITY nbsp   "&#160;">]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="no"/>

  <xsl:template match="/">
    <memberdata>  
      <xsl:for-each select="memberdata/memberinfo">
        <xsl:sort select="SortKey"/>
        <memberdata>
          <fo:block text-align-last="justify">
            <xsl:if test="Contacts[.!='']">
              <Contacts><xsl:value-of select="Contacts" /></Contacts>
              <xsl:text>&#10;</xsl:text>
            </xsl:if>
            <fo:leader leader-pattern="space" />
            <xsl:if test="Address1[.!='']">
              <Address1><xsl:value-of select="Address1" /></Address1>
              <xsl:text>&#10;</xsl:text>
            </xsl:if>
          </fo:block>
        </memberdata>
      </xsl:for-each>
    </memberdata> 
  </xsl:template>
</xsl:stylesheet>

但是,您似乎不太可能想要在输出中混合使用<fo:*>元素和其他元素(<memberdata>)...除非您计划稍后处理它们以生成完整的FO文档。所以上面可能不是你需要的解决方案。

(另请参阅@ Tomalak关于如何改进XSLT的优点。我会因为for-each与apply-templates的问题而与他不同......这实际上取决于几个因素以及您的优先级。 )