Для начала XSLT заменит участник href на соответствующий элемент партии.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:fpml="http://www.example.com">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="fpml:partyReference[@href]">
<xsl:variable name="href" select="@href" />
<partyReference>
<party>
<xsl:apply-templates select="//party[@id=$href]" mode="dereference" />
</party>
</partyReference>
</xsl:template>
<xsl:template match="party" />
<xsl:template match="party" mode="dereference">
<xsl:element name="{@id}">
<xsl:apply-templates select="node()|@*[not(local-name()='id')]" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Видя, как я не знаю, что ваш fpml
префикс связывается, я вставил какой-то образец URI для этого пространства имен.
Первый подходящий шаблон node()|@*
- это стандартный подход, который просто скопирует все, что не соответствует никаким другим шаблонам.
Второй шаблон, соответствующий fpml:partyReference[@href]
, будет принимать любую сторонуReference с атрибутом href (в данном пространстве имен), извлекает значение переменной @href для переменной и затем применяет шаблоны к любому элементу партии, где атрибут id соответствует этому значению href , Обратите внимание, как он вводит режим с названием «разыменование». Это имя произвольно и что-то я выбрал.
Следующий шаблон пуст, который соответствует всем party
элементам и ничего не делает. Они не будут скопированы. Это позволяет избежать повторного копирования партии после того, как она уже была помещена в ссылку ранее.
И, наконец, шаблон, который соответствует всем элементам party
, но только в режиме dereference
. Это создаст новый элемент с именем имени значения атрибута id
, а затем применит шаблоны к атрибутам и дочерним узлам, за исключением атрибута id (так как вы не хотите, чтобы его копировали на выходе). Это будет просто по умолчанию для копирования содержимого.
Поскольку у меня недостаточно информации о том, что эти атрибуты partyIdScheme
на вашем входе делают, я не преобразовал это содержимое. Вышеприведенное должно дать вам некоторые указания о том, как это решить. Обратите внимание, что вам нужно будет изменить XSLT с правильным пространством имен для префикса fpml
и что вам может потребоваться изменить использование пространства имен, поскольку ваши XML-выдержки оставляют неопределенность в отношении того, что находится в пространстве имен (нам нужно будет увидеть хорошо сформированные XML-документ, чтобы понять это, а не выдержки).
Также, когда я пытаюсь выполнить сопоставление шаблона для Party1, который является преобразованным элементом XSLT, синтаксический анализатор не может его распознать. Но когда я сопоставляю элемент-участник (который является исходным), синтаксический анализатор может распознать его.
Это потому, что XSLT работает только с входным документом. Он перемещает вход, сопоставляет его части с шаблонами и выполняет инструкции в этих шаблонах. Это декларативный язык. Таким образом, генерируемый результат не является частью ввода и не будет влиять на него. Для этого вам понадобится несколько преобразований XSLT.
Возможно, что предоставленный вами XML использует некоторые технологии, такие как XInclude или другие схемы ссылок. Вы можете получить желаемые результаты с помощью парсеров, которые поддерживают правильную технологию или некоторую библиотеку, которая реализует такие схемы ссылок, поэтому, прежде чем продолжать использовать XSLT, посмотрите, есть ли что-то, что уже делает то, что вы пытаетесь.
EDIT: пример соответствия нескольких элементов в том же количестве шаблонов, что и выше. Обратите внимание, что это будет работать, только если атрибут id
во входном XML уникален для каждого элемента, на который можно ссылаться href
. В противном случае результаты могут быть неверными.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:fpml="http://www.example.com">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="fpml:partyReference[@href]|fpml:accountReference[@href]|fpml:payerPartyReference[@href]">
<xsl:variable name="href" select="@href" />
<xsl:element name="{local-name()}" namespace="{namespace-uri()}">
<xsl:apply-templates select="//*[@id=$href]" mode="dereference" />
</xsl:element>
</xsl:template>
<xsl:template match="party|account|payerParty" />
<xsl:template match="party|account|payerParty" mode="dereference">
<xsl:element name="{local-name()}" namespace="{namespace-uri()}">
<xsl:element name="{@id}">
<xsl:apply-templates select="node()|@*[not(local-name()='id')]" />
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Ваш вопрос непонятен. Пожалуйста, опубликуйте [mcve], включая XML, ваш текущий XSLT и ожидаемый результат. - Я * думаю * вы хотите узнать, как использовать [ключ] (https://www.w3.org/TR/xslt/#key). –