Как я могу предоставить значения атрибутов из другого XML-документа, используя XSLT? - PullRequest
0 голосов
/ 09 мая 2019

У меня есть два XML-документа.Один (назовем это xml1) перечисляет серию элементов 'w', каждый из которых имеет атрибут 'orig'.В другом документе (xml2) перечислены связанные серии элементов 'w', но с другими атрибутами ('норма').Я хочу объединить два документа так, чтобы у меня была только одна серия элементов со всеми атрибутами («оригинал» и «норма»).

Это звучит достаточно просто, но я не могу получитькод, чтобы работать, я не могу получить код для выбора одного значения атрибута «норма», в отличие от всех доступных значений.

Я попытался просто выбрать значение атрибутов из xml2 с помощьюкоманда

<xsl:value-of select="document('xml2.xml')//@norm"/>

, но все, что она делает, это выбирает значения ВСЕХ атрибутов 'norm' в xml2.

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

Если я использую команду «для каждой», ни один элемент не будет выбран.

Вот пример xml1:

    <text>
        <seg type="stanza" n="1">
            <l n="1">
                <w xml:id="1" orig="Haile"/>
                <w xml:id="2" orig=","/>
                <w xml:id="3" orig="sterne"/>
                <w xml:id="4" orig="superne"/>
                <w xml:id="5" orig="!"/>
            </l>
        </seg>
    </text>

Вот пример xml2:

    <text>
        <seg type="stanza" n="1">
            <l n="1">
                <w xml:id="1" norm="Hail"/>
                <w xml:id="2" norm=","/>
                <w xml:id="3" norm="star"/>
                <w xml:id="4" norm="supernal"/>
                <w xml:id="5" norm="!"/>
            </l>
        </seg>
    </text>

Я хотел бы получить это:

    <text>
        <seg type="stanza" n="1">
            <l n="1">
                <w xml:id="1" orig="Haile" norm="Hail"/>
                <w xml:id="2" orig="," norm=","/>
                <w xml:id="3" orig="sterne" norm="star"/>
                <w xml:id="4" orig="superne" norm="supernal"/>
                <w xml:id="5" orig="!" norm="!"/>
            </l>
        </seg>
    </text>

Пока что мой xslt-файл выглядит так:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"    
    xpath-default-namespace="http://www.tei-c.org/ns/1.0"
    xmlns="http://www.tei-c.org/ns/1.0"
    version="2.0">

    <xsl:output method="xml" indent="no"/>

    <!-- select the entirety of the document -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>    

    <!-- combine attributes from separate files -->
    <xsl:template match="//w">
        <xsl:copy>
             <xsl:apply-templates select="@*"/>
                  <xsl:attribute name="norm">
                       <xsl:value-of select="document('xml2.xml')//@norm"/>
                  </xsl:attribute>
        </xsl:copy>        
    </xsl:template>

</xsl:stylesheet>

Пожалуйста, помогите мне, если можете.Спасибо.

Ответы [ 2 ]

0 голосов
/ 09 мая 2019

Поиск лучше всего обрабатывать с помощью клавиши . Попробуйте (не проверено):

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="norm" match="w" use="@xml:id" />

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="w">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:copy-of select="key('norm', @xml:id, document('xml2.xml'))/@norm"/>   
    </xsl:copy>        
</xsl:template>

</xsl:stylesheet>
0 голосов
/ 09 мая 2019
<xsl:output method="xml" indent="yes"/>
    <xsl:variable name="imp" select="document('Stanza1.xml')"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="l">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:for-each select="w">
                <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:copy-of select="$imp/text/seg/l/w[@xml:id = current()/@xml:id]/@norm"/>
                </xsl:copy>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
You may use like this
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...