Скажем, у меня есть XML-данные, подобные этому:
<root>
<subs>
<sub>
<values>
<value attribute="a">1</value>
<value attribute="a">2</value>
<value attribute="c">3</value>
<value attribute="c">4</value>
</values>
</sub>
<subOther>
<otherValues attribute="c">
<otherValue attribute="a">1</value>
<otherValue attribute="a">2</value>
<otherValue attribute="b">3</value>
<otherValue attribute="a">4</value>
</otherValues>
</subOther>
</subs>
</root>
Я пытаюсь создать шаблон XSLT, который соответствует всем узлам на пути к /root/subs/subOther/otherValues/otherValue[attribute="b"]
.
Пока чтоэто самое близкое, что я получил:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<!--IDENTITY TEMPLATE -->
<xsl:template match="@*|node()">
<xsl:apply-templates select="node()" />
</xsl:template>
<xsl:template match="//*[ancestor-or-self::[@attribute='b']]">
<xsl:copy>
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Но это выдает ошибку, говорящую о том, что есть неожиданный токен [
. Я пробовал несколько комбинаций, но они либо вообще ничего не совпадают, либо слишком много (то есть все), либо выдают какую-то ошибку.
Редактировать: Я обновил примери ожидается, что будет немного яснее. Также обратите внимание, что это очень упрощенный XML. В моем реальном файле рассматриваемый атрибут может находиться в любом листовом узле любого допустимого элемента для этого уровня, поэтому я должен использовать более общий путь с использованием *
и неизвестные пути с //
. Так, например, один из элементов value
может быть элементом с attribute="b"
, и он вызовет тот же результат.
Редактировать 2: Ожидаемый результат - выбратьузлы, которые имеют путь, ведущий к любому левому потомку с атрибутом, равным определенному значению. В моей схеме XSD в общей сложности около 100 возможных листовых узлов. Сценарий использования заключается в том, что атрибут в вопросительных знаках, какие элементы данных имели изменения, и мне нужно в основном создать «diff», где полный файл сокращается только до тех узлов, в которых результатом являются только те элементы, которые изменились, и их родители,В приведенном выше небольшом примере attrubute="b"
- это указание на то, что мне нужно скопировать этот узел, и, следовательно, я ожидаю точного результата:
<root> <!-- Copied because part of the path -->
<subs> <!-- Copied because part of the path -->
<sub> <!-- Copied because part of the path -->
<values> <!-- Copied because part of the path -->
<value attribute="b">3</value> <!-- Copied because it matches the attribute -->
</values>
</sub>
</subs>
</root>
Надеюсь, это имеет смысл. Кроме того, я исправил опечатку на xsl:stylesheet
, который самозакрывающийся.