Я читаю между строк немного, но думаю, я знаю, что вы пытаетесь сделать.
Я бы предложил сделать это с двумя отдельными XSL. Конечно, можно объединить два прохода XSL в один XSL, но фактическая реализация зависит от используемой вами библиотеки XSL (здесь есть некоторые подробности, если вам интересно: http://www.oreillynet.com/xml/blog/2006/08/multistage_xslt_scripts.html)
Первый проход должен пройти через все ваши термины и присвоить номера тем, которые помечены как «Nd». Я догадываюсь:
(a) Если у них есть идентификатор, их тип должен быть изменен на «pt», и
(b) Порядок этих элементов не является конкретным.
Причина, по которой я предлагаю сделать это в качестве отдельного прохода, заключается в том, что один из ваших терминов может ссылаться на другой термин, который сам по себе является типом «Nd». Если бы это было так, то у него не было бы действительного номера для ссылки (поскольку ни один не был бы назначен)
XSL для выполнения этого шага будет выглядеть примерно так:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="term[termType = 'Nd']">
<term>
<xsl:copy-of select="termName"/>
<termId><xsl:value-of select="position()"/></termId>
<termType>pt</termType>
<xsl:copy-of select="relation" />
</term>
</xsl:template>
<xsl:template match="/">
<zthes>
<xsl:apply-templates select="zthes/term[termType = 'Nd']"/>
<xsl:copy-of select="zthes/term[termType = 'pt']"/>
</zthes>
</xsl:template>
</xsl:stylesheet>
Вторым шагом было бы взять выходные данные этого преобразования и протолкнуть его через второе преобразование, которое будет «заполнять» идентификаторы терминов «отношение». Это довольно простое преобразование идентичности (точная, рекурсивная копия) с одним специальным правилом. Специальное правило идентифицирует termIds внутри узлов отношений и заменяет правильный termId на основе сопоставления имен. Это преобразование выглядит так:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="relation/termId">
<termId>
<xsl:value-of select="/zthes/term[termName=current()/../termName]/termId"/>
</termId>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Я ожидаю, что это сделает примерно то, что вы после. Это не будет работать как есть на ваших текущих входных данных, потому что ваш текущий ввод на самом деле является недопустимым XML. :) Чтобы это исправить:
- Измените 'Zthes' на 'zthes' в
открывающий тег XML чувствителен к регистру
- Внутри первого блока 'Relations' убедитесь, что вы закрыли 'termId'
узел. На данный момент вы открываете
это дважды и не закрывая его.
- Внутри 'termName' блока 'отношение' вы ссылались на 'Term2'
когда ты имел в виду «срок 2».
Есть разница между пробелами, которая
остановит их соответствие.
Удачи!