【问题标题】:XSL FO inline alignment on an existing sort/conditional XSL现有排序/条件 XSL 上的 XSL FO 内联对齐
【发布时间】:2011-01-20 18:29:55
【问题描述】:

我需要让右对齐和左对齐在同一行中工作。查看类似的回复,我发现了以下建议,

<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>

【问题讨论】:

  • 您的 XSLT 代码不包含 &lt;fo:block&gt;,我不清楚您要做什么。
  • @Tom:没有所需的输出,这不是一个真正的问题。
  • 这不是一个定义明确的问题。

标签: xslt xsl-fo


【解决方案1】:

独立于您的问题的实际答案(不可能以问题所在的当前形式给出),我想建议您对 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>
  • 避免使用&lt;xsl:for-each&gt;,改用不同的模板和&lt;xsl:apply-templates&gt;。这会导致代码更干净、重复更少且嵌套更少。它还可以提高样式表的处理效率,因为 XSLT 处理器针对模板匹配进行了优化,并且可以并行执行模板。
  • 请注意,您可以对多个元素使用同一个模板,请参阅上面的第三个模板。
  • 避免通过这样的结构添加换行符:<xsl:text>
    </xsl:text>
    。这样做会破坏源代码的可读性,并且在源代码格式化后容易出错(我已经在你的问题中这样做了,以便能够首先正确缩进你的代码)。改用字符引用&amp;#10; 来分隔源代码布局和输出布局。
  • 请注意,您可以使用&lt;xsl:copy-of&gt; 复制元素,无需使用&lt;foo&gt;&lt;xsl:value-of select="foo" /&gt;&lt;/foo&gt;

【讨论】:

  • Tomalak thx 但导入到 InDesign CS5 时会导致 2 个单独的行项目,全部左对齐。
  • 这里有两个单独的问题:(a) 您需要样式表的什么输出,以及 (b) 如何让样式表生成 (a) 中指定的输出。您对 InDesign 的评论表明您不确定 (a)。如果是这样,您需要先弄清楚这一点,然后才能希望得到 (b) 的任何有用答案。
【解决方案2】:

从表面上看你的要求,这似乎就是你所要求的,它合并了排序、条件和 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>

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

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

【讨论】:

  • LarsH thx 当我尝试在 Dreamweaver 中验证您的代码时,我收到以下错误消息:前缀 'fo' 尚未映射到任何 URI[xml] 怎么办?
  • @Tom,我给你的 XSLT 确实不是格式良好的 XML。道歉。但是,如果您打算开发样式表,则需要学习命名空间声明的基础知识。由于尚未声明命名空间前缀 'fo',因此您需要为其添加声明,通常在 xsl:stylesheet 元素上:&lt;xsl:stylesheet xmlns:fo="http://www.w3.org/1999/XSL/Format" ...&gt;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多