XSLT-создание узла из другого контекста

У меня есть следующий XML-файл:

<config>
    <files>
        <file uuid="uuid-file1">
            <name>File1</name>
        </file>
        <file uuid="uuid-file2">
            <name>File2</name>
        </file>
        <file uuid="uuid-file3">
            <name>File3</name>
        </file>
        <file uuid="uuid-file4">
            <name>File3</name>
        </file>
    </files>
    <folders>
        <folder uuid="root" />
        <folder uuid="folder1">
            <member ref="uuid-file1" />
        </folder>
        <folder uuid="folder2">
            <member ref="uuid-file2" />
        </folder>
    </folders>
</config>

ie = file1 ссылается на folder1 и file2 ссылается на folder2.
file3 и file4 не находятся в папке.

Моя проблема:

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

Пример (file3 и file4 не находятся в папке):

<config>
    <files>
        <file uuid="uuid-file1">
            <name>File1</name>
        </file>
        <file uuid="uuid-file2">
            <name>File2</name>
        </file>
        <file uuid="uuid-file3">
            <name>File3</name>
        </file>
        <file uuid="uuid-file4">
            <name>File4</name>
        </file>
    </files>
    <folders>
        <folder uuid="root" >
            <member ref="uuid-file3" />
            <member ref="uuid-file4" />
        </folder>
        <folder uuid="folder1">
            <member ref="uuid-file1" />
        </folder>
        <folder uuid="folder2">
            <member ref="uuid-file2" />
        </folder>
    </folders>
</config>

Я пытаюсь сделать это с циклом ‘for-each’, но я не знаю, как создать новый узел в папке’ root’, когда я просматриваю узел «files».

Мне нужна ваша помощь 🙂

С уважением,
Зидо

1 ответ

  1. Попробуйте так:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    >
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:key name="folder" match="folder" use="member/@ref" />
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="folder[@uuid='root']">
        <xsl:copy>
            <xsl:for-each select="/config/files/file[not(key('folder', @uuid))]">
                <member ref="{@uuid}"/>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>
    

    Обратите внимание, что это предполагает, что мы знаем, как определить «корневую» папку (в данном примере ее @uuidзначение буквально строка «root»). Эта часть вашего вопроса не совсем ясна.