Поиск XSLT из внешнего файла xml - PullRequest
0 голосов
/ 07 марта 2020

Я знаю, что здесь есть много вопросов (и ответов) по поиску внешних файлов xml через xslt. Тем не менее, я до сих пор не могу разобраться с логикой c ключевой функции, поэтому мне сложно применить другие решения для моего варианта использования.

У меня есть два xml файла:

верс. xml

<TEI>
  <div>
    <l id="A001" corresp="B001">First line of VersA</l>
    <l id="A002" corresp="B002">Second line of VersA</l>
    <l id="A003" corresp="B003">Third line of VersA</l>
  </div>
</TEI>

и

верс. xml

<TEI>
  <div>
    <l id="B001" corresp="A001">First line of VersB</l>
    <l id="B002" corresp="A002">Second line of VersB</l>
    <l id="B003" corresp="A003">Third line of VersB</l>
  </div>
</TEI>

Файлы ссылаются друг на друга через corresp -атрибут.

Я пытаюсь выяснить таблицу стилей xsl ( trans.xsl ), которая анализирует versA . xml, печатает свой собственный текстовый узел и затем ищет соответствующий текстовый узел в верси. xml

trans.xsl

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:variable name="vB" select="document('versB.xml')/TEI/div/l"/>

<xsl:template match="/TEI/div/l">
I found ID <xsl:value-of select="@id"/> in versA.xml.
How can I get the corresponding node in versB.xml which has the ID <xsl:value-of select="@corresp"/>?
</xsl:template>


</xsl:stylesheet>

Что я могу сделать, это вывести идентификаторы versA. xml и получить доступ к versB. xml. Однако мне очень трудно настроить соответствующую функцию клавиш, которая принимает значение corresp от versA. xml для поиска соответствующего идентификатора в versB. xml

Я был бы рад, если бы кто-нибудь мог объяснить, как этого можно достичь.

По соображениям совместимости предпочтительнее использовать версию 1.0 для xslt.

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

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:key name="ref" match="TEI/div/l" use="@id"/>

<xsl:template match="/TEI/div/l">

  <xsl:variable name="corresp" select="@corresp"/>
  <xsl:value-of select="."/> corresponds to 
  <xsl:for-each select="document('versB.xml')">
     <xsl:value-of select="key('ref', $corresp)"/>
   </xsl:for-each>

</xsl:template>

</xsl:stylesheet>

1 Ответ

1 голос
/ 07 марта 2020

Вам необходимо объявить ключ с помощью xsl:key, присвоив ему name, который вы можете выбрать, используя match шаблон узлов, для которых вы хотите «проиндексировать», для которого вы хотите объявить ключ, и определить значение ключа с атрибутом use, выражение XPath:

<xsl:key name="ref" match="TEI/div/l" use="@id"/>

Чтобы использовать ключ, вы вызываете функцию key с именем объявленного ключа в качестве первого аргумента, значение ключа как второй аргумент и, в XSLT 2 или более поздней версии, документ или поддерево, которое вы хотите найти, в качестве третьего аргумента: key('ref', @corresp, document('versB.xml')).

Если вы действительно ограничены XSLT 1, то с двумя разными документами, так как третий аргумент функции key не поддерживается, вам необходимо переключить «контекстный документ» с помощью for-each, например:

<!-- need to store value of main input document we want to lookup in variable -->
<xsl:variable name="corresp" select="@corresp"/>

<!-- now we change the context document to be able to apply the key function on secondary input -->
<xsl:for-each select="document('versB.xml')">
   <xsl:value-of select="key('ref', $corresp)"/>
</xsl:for-each>

В обоих примерах использования функции key, описанной выше Предположим, вы делаете их в контексте xsl:template match="/TEI/div/l", так что @corresp выбирает значение этого атрибута элемента l в вашем основном входе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...