XSLT Как выбрать значение атрибута узла с помощью xsl: for-each и xsl: if - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть файл XML для рендеринга с XSLT 1.0.

Мой cas следующий:

Если значение longName равно "Oui_Combi"

$Publication = prodDate значение ( 21.11.2018 )

остальное

$Publication = productionDates значение ( 17.11.2018, 21.11.2018 )

Я не уверен, что мой синтаксис правильный для for-each и / или для xsl-if

XML-файл:

<?xml version="1.0" encoding="UTF-8"?>
<Manuscript dateAndTime="2018-11-16T10:20:59.177+01:00" renderEPS="" forMediation="false">
    <Order>
        <OrderHeader productionDates="17.11.2018, 21.11.2018">
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            <Criterion name="TypePublicity" ordering="1">
                TypePubOccasionnel <ValueParameter longName="Occasionnel"/>
            </Criterion>
            <Criterion name="JuraCombi" ordering="2">
                Oui_Combi <ValueParameter longName="Oui_Combi"/>
                                          ^^^^^^^^^^^^^^^^^^^^
            </Criterion>
        </OrderHeader>
        <FirstIssueData prodDate="21.11.2018"></FirstIssueData>
    </Order>            ^^^^^^^^^^^^^^^^^^^^^
</Manuscript>

XSL-часть, где я создаю свою переменную:

  <xsl:for-each select="Order/OrderHeader/Criterion">
    <xsl:if test="@name = 'JuraCombi'">

        <xsl:if test="ValueParameter/@longName = 'Oui_Combi'">
            <xsl:variable name="JuraCombi">
                OUI
            </xsl:variable>
            <xsl:variable name="Publication">
                <xsl:value-of select="/Order/FirstIssueData/@prodDate" />
            </xsl:variable>
        </xsl:if>

        <xsl:if test="ValueParameter/@longName != 'Oui_Combi'">
            <xsl:variable name="JuraCombi">
                NON
            </xsl:variable>
            <xsl:variable name="Publication">
                <xsl:value-of select="/Order/OrderHeader/@productionDates" />
            </xsl:variable>
        </xsl:if>

    </xsl:if>
</xsl:for-each>

...

XSL-часть, где я хочу напечатать свою переменную $Publication:

<xsl:template match="OrderHeader">
    <fo:table 
        table-layout="fixed" 
        width="18cm" 
        font-size="10pt" 
        padding="1.0pt">
        <fo:table-column column-width="30mm"/>
        <fo:table-column column-width="60mm"/>
        <fo:table-column column-width="30mm"/>
        <fo:table-column column-width="60mm"/>
        <fo:table-body>

            ...

            <fo:table-row>
                <fo:table-cell>
                    <fo:block padding="0.5cm">
                        Parutions
                    </fo:block>
                </fo:table-cell>
                <fo:table-cell number-columns-spanned="3">
                    <fo:block padding="0.5cm">
                        <xsl:copy-of select="$Publication" />
                    </fo:block>              ^^^^^^^^^^^^
                </fo:table-cell>
            </fo:table-row>

            ...

        </fo:table-body>
    </fo:table>
</xsl:template>

Может быть, мы можем достичь этого без для каждого?

Ни один онлайн-инструмент / средство проверки XSLT не может дать мне подробную ошибку, но рендеринг останавливается!

Спасибо за помощь

1 Ответ

0 голосов
/ 16 ноября 2018

Область действия переменной XSLT ограничена элементом, содержащим xsl:variable, и применяется только к выражениям, которые встречаются после xsl:variable. То есть «привязка видна для всех последующих братьев и сестер и их потомков», как сказано в спецификации XSLT 1.0 (см. https://www.w3.org/TR/1999/REC-xslt-19991116#local-variables).

Таким образом, ваши переменные находятся вне области действия xsl:if, в котором они объявлены.

Нужно вывернуть свою логику наизнанку и поместить условную логику в каждый элемент xsl:variable. Что-то вроде (не проверено):

<xsl:variable name="JuraCombi">
  <xsl:choose>
    <xsl:when test="ValueParameter/@longName = 'Oui_Combi'">OUI</xsl:when>
    <xsl:otherwise>NON</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="Publication">
  <xsl:choose>
    <xsl:when test="ValueParameter/@longName = 'Oui_Combi'">
      <xsl:value-of select="/Manuscript/Order/FirstIssueData/@prodDate" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="../@productionDates" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>

Обратите внимание, что ваш XPath для выбора @prodDate ничего не выберет. Требуется шаг /Manuscript, поскольку Manuscript является элементом документа.

Не ясно, как ваш код для объявления переменных относится к шаблону, который создает fo:table. Чтобы значения переменных могли быть применимы, вам нужно иметь xsl:apply-templates, который выбирает OrderHeader, чтобы быть в пределах объема объявлений переменных, и вам нужно будет передать значения переменных в шаблон используя xsl:with-param и xsl:param. См https://www.w3.org/TR/1999/REC-xslt-19991116#section-Passing-Parameters-to-Templates.


Я не уверен, что знаю, что вы имеете в виду в своем комментарии, поэтому это лучшее решение, которое я могу интуитивно понять:

<xsl:template match="Order">
  <xsl:variable name="JuraCombi">
    <xsl:choose>
      <xsl:when test="OrderHeader/Criterion[@name = 'JuraCombi']/ValueParameter/@longName = 'Oui_Combi'">OUI</xsl:when>
      <xsl:otherwise>NON</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="Publication">
    <xsl:choose>
      <xsl:when test="$JuraCombi = 'OUI'">
        <xsl:value-of select="FirstIssueData/@prodDate" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="OrderHeader/@productionDates" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <fo:table 
      table-layout="fixed" 
      width="18cm" 
      font-size="10pt" 
      padding="1.0pt">
    <fo:table-column column-width="30mm"/>
    <fo:table-column column-width="60mm"/>
    <fo:table-column column-width="30mm"/>
    <fo:table-column column-width="60mm"/>
    <fo:table-body>
      <fo:table-row>
        <fo:table-cell>
          <fo:block padding="0.5cm">
            Parutions
          </fo:block>
        </fo:table-cell>
        <fo:table-cell number-columns-spanned="3">
          <fo:block padding="0.5cm">
            <xsl:copy-of select="$Publication" />
          </fo:block>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-body>
  </fo:table>
</xsl:template>
...