Линейное выравнивание XSL FO по существующему виду / условному XSL - PullRequest
0 голосов
/ 20 января 2011

Мне нужно, чтобы выравнивание по правому и левому выравниванию работало в одной строке. Просматривая похожие ответы, я нашел следующую рекомендацию,

<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 голосов
/ 21 января 2011

Принимая ваш запрос за чистую монету, кажется, это то, о чем вы просите, что объединяет сортировку, условия и 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.Таким образом, приведенное выше может оказаться не совсем тем решением, которое вам нужно.

(См. Также хорошие моменты @ Томалака о том, как улучшить XSLT. Я бы с ним не согласился только в вопросе «для каждого» и «применения-шаблонов»).... это действительно зависит от нескольких факторов и ваших приоритетов.)

0 голосов
/ 20 января 2011

Независимо от фактического ответа на ваш вопрос (который невозможно дать в текущей форме, в которой находится вопрос), я хотел бы предложить несколько улучшений вашего общего подхода к 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><br> </xsl:text>. Это нарушает читабельность исходного кода и приводит к ошибкам, как только исходный код отформатирован (я уже сделал это в вашем вопросе, чтобы в первую очередь иметь возможность правильно отступать в код) . Вместо этого используйте ссылки на символы &#10;, чтобы разделить макет исходного кода и макет вывода.
  • Обратите внимание, что вы можете использовать <xsl:copy-of>, чтобы сделать копию элемента, не нужно делать <foo><xsl:value-of select="foo" /></foo>.
...