XSLT 1.0 Проблемы с реализацией рекурсивного шаблона - PullRequest
0 голосов
/ 26 июня 2018

Я довольно новичок в XSLT и борюсь с реализацией рекурсивного шаблона, который проходит через несколько текстовых узлов и ищет совпадение.При создании рекурсивного шаблона я получаю сообщение об ошибке: «Обязательный тип элемента первого операнда '/' - это node (); предоставленное значение имеет тип элемента xs: string».Я не знаю, как выбрать несколько узлов в качестве узлов вместо строки.

Цель: у меня есть несколько тестовых узлов, таких как

<Chain>1 3 4 7 20 50 72 ...</Chain>

Я хочу перебрать эти узлы, чтобыискать соответствующий номер.Когда это число найдено, мне нужно выбрать подстроку родительского атрибута элемента.

Вот часть таблицы стилей с рекурсивным шаблоном:

<xsl:template match="/l:LandXML/h:HexagonLandXML/h:Point/h:PointCode">
<xsl:variable name="id2" select="../@uniqueID"/>
  <xsl:call-template name="tests">
  <xsl:with-param name="input" select="/l:LandXML/h:HexagonLandXML/h:PlanFeature/h:CoordGeom/h:Spline/h:Chain"/>
  <xsl:with-param name="id" select="$id2"/>
  </xsl:call-template>
</xsl:template>

<xsl:template name="tests">
<xsl:param name="id"/>
<xsl:param name="input"/>
<xsl:choose>
    <xsl:when test="substring-before($input, ' ') = $id">
        <xsl:value-of select="format-number(substring-before(substring-after($input/../@oID, '_'), '_'), '#')"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:call-template name="tests">
            <xsl:with-param name="input" select="substring-after($input, ' ')"/>
            <xsl:with-param name="id" select="$id"/>
        </xsl:call-template>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>

Для лучшего понимания, полноеXML и XSLT здесь: https://xsltfiddle.liberty -development.net / 94hvTzd / 17

Заранее благодарим за любую помощь.

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Итак, вы хотите узнать, содержит ли

<Chain>1 3 4 7 20 50 72 ...</Chain>

, скажем, 50?

Здесь нет необходимости в рекурсивном шаблоне.Строковые функции XPath могут делать это просто отлично.Для XPath 1.0 используйте

//Chain[contains(concat(' ', ., ' '), concat(' ', $val, ' '))]

, где $val равно '50'.concat() гарантирует, что частичных совпадений нет, и что совпадения в начале и в конце обнаруживаются.

Для XPath 2.0 и выше вы можете использовать tokenize().

//Chain[tokenize(., ' ') = $val]
0 голосов
/ 26 июня 2018

Ваш шаблон в <xsl:with-param name="input" select="substring-after($input, ' ')"/> передает строковое значение, строковое значение не имеет родительского узла, поэтому вам придется хранить / передавать исходный элемент как отдельный параметр.Обратите внимание, что у вас в xsltfiddle есть доступ (и вы используете его) к Saxon 9.8 HE, процессору XSLT 3, где вы можете избежать хлопот, связанных с использованием рекурсивного шаблона, например, tokenize(Chain, ' ')[. = $id] или аналогичным.

...