XSLT Как выбрать значение атрибута узла с помощью xsl:for-each и xsl:if
У меня есть файл 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 ответ
Область действия переменной XSLT ограничена элементом, который содержит xsl:variable
и это относится только к выражениям, которые встречаются после xsl:variable
, Т.е. "привязка видима для всех последующих братьев и сестер и их потомков", как сказано в спецификации XSLT 1.0 (см. https://www.w3.org/TR/1999/REC-xslt-19991116).
Таким образом, ваши переменные выходят за рамки 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.
Я не уверен, что знаю, что вы имеете в виду в своем комментарии, так что это лучшее решение, которое я могу интуитивно понять:
<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>