用于比较和合并两个 XML 文件的 XSLT document() 函数

XSLT document() function to compare and combine two XML files

提问人:user24000 提问时间:9/27/2023 最后编辑:user24000 更新时间:9/27/2023 访问量:46

问:

我正在使用 Notepad++ 和 XSLT 1.0 来转换 XML 文件。 有一个 Data.xml 文件和一个 Dict.xml 文件,后者包含字符串的翻译。我希望在输出中转换 Data.xml 中的字符串。

数据.xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Root>
    <Textabschnitt>
        <Root ID="2050775654055586328">Administration</Root>
    </Textabschnitt>
    <Textabschnitt ID="13667714361645396460">All</Textabschnitt>
    <Textabschnitt ID="4765748458590838957">Application</Textabschnitt>
    <Textabschnitt>
        <Tabelle>
            <Zelle>
                <Textabschnitt ID="14682159838120944212">Name</Textabschnitt>
            </Zelle>
            <Zelle>
                <Textabschnitt ID="2960145709916589219">Status</Textabschnitt>
            </Zelle>
        </Tabelle>
    </Textabschnitt>
</Root>

Dict.xml:

<?xml version="1.0" encoding="utf-8"?>
<DICT>
    <DICT_ENTRY LANG_ID="ro">
        <uicontrol id="2050775654055586328">Administrare</uicontrol>
    </DICT_ENTRY>
    <DICT_ENTRY LANG_ID="ro-RO">
        <uicontrol id="13667714361645396460">Toate</uicontrol>
    </DICT_ENTRY>
    <DICT_ENTRY LANG_ID="ro-RO">
        <uicontrol id="4765748458590838957">Aplicație</uicontrol>
    </DICT_ENTRY>
    <DICT_ENTRY LANG_ID="ro-RO">
        <uicontrol id="14682159838120944212">Nume</uicontrol>
    </DICT_ENTRY>
    <DICT_ENTRY LANG_ID="ro-RO">
        <uicontrol id="2960145709916589219">Stare</uicontrol>
    </DICT_ENTRY>
</DICT>

输出应与 Data.xml 相同,但将 Textabschnitt 元素的内容替换为 @id 属性标识的翻译。

我在网上和 O'Reilly 中看了很多 document() 用法的例子。但是,我无法让它读取文件并输出它。

我一直在尝试的 XSLT(在许多其他尝试中)是:

XSLT的:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

     <xsl:param name="translatedStrings" select="document('Dict.xml')"/>


<!--Identity template, provides default behavior that copies all content into the output -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

<!-- replace string with translated string, identified with ID (first attempt) -->
    <xsl:template match="//@ID">
        <xsl:variable name="id" select="." />
        <xsl:attribute name="id">
            <xsl:value-of select="$id"/>
        </xsl:attribute>
        <xsl:value-of select="$translatedStrings/DICT/DICT_ENTRY/uicontrol[@id=$id][1]"/>
    </xsl:template>

</xsl:stylesheet>

这个特定的输出会产生一个空白文件,我认为这是最后一个语句出了问题。xsl:value-of

我确信我正在做一些非常基本和错误的事情,但不确定是什么。任何指向正确方法和语法的指针都将不胜感激。谢谢。

编辑:为清楚起见,我想要的输出是:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Root>
    <Textabschnitt>
        <Root ID="2050775654055586328">Administrare</Root>
    </Textabschnitt>
    <Textabschnitt ID="13667714361645396460">Toate</Textabschnitt>
    <Textabschnitt ID="4765748458590838957">Aplicație</Textabschnitt>
    <Textabschnitt>
        <Tabelle>
            <Zelle>
                <Textabschnitt ID="14682159838120944212">Nume</Textabschnitt>
            </Zelle>
            <Zelle>
                <Textabschnitt ID="2960145709916589219">Stare</Textabschnitt>
            </Zelle>
        </Tabelle>
    </Textabschnitt>
</Root>
XPath XSLT 文档

评论

0赞 michael.hor257k 9/27/2023
虽然您的尝试不会产生预期的结果,但它也不应产生空白文件。我强烈建议您在提供有用错误消息的环境中进行测试。
0赞 user24000 9/27/2023
谢谢迈克尔。工作计算机,所以我在他们目前允许的范围内受到限制,但会继续要求更好的工具。

答:

1赞 y.arazim 9/27/2023 #1

我想你想做这样的事情:

<xsl:template match="Textabschnitt[@ID]">
    <xsl:variable name="id" select="@ID" />
    <Textabschnitt ID="{$id}">
        <xsl:value-of select="$translatedStrings/DICT/DICT_ENTRY/uicontrol[@id=$id]"/>
    </Textabschnitt>
</xsl:template>

顺便说一句,如果您使用的是 XSLT 1.0,您的样式表不应声明 .version="2.0"


编辑:

如果您不仅要翻译其任何后代的文本,还要翻译其任何后代的文本,那么您可以执行以下操作:Textabschnitt

<xsl:template match="*[ancestor-or-self::Textabschnitt and @ID]/text()">
    <xsl:variable name="id" select="../@ID" />
    <xsl:value-of select="$translatedStrings/DICT/DICT_ENTRY/uicontrol[@id=$id]"/>
</xsl:template>

评论

0赞 user24000 9/27/2023
谢谢@y.arazim。我已经更正了版本号和读取的文件的名称,以及您的建议,但它仍然生成一个空白文件。
0赞 user24000 9/27/2023
我也试过:它仍然产生一个空白的输出文件。所以我一定是在做更严重的错误。<xsl:value-of select="document('Dict.xml')/DICT/DICT_ENTRY/uicontrol[@id=$id]"/><xsl:value-of select="document('Dict.xml')/DICT/DICT_ENTRY/uicontrol[1]"/>
1赞 y.arazim 9/27/2023
您的处理器是否可能不允许访问外部文件?
0赞 user24000 9/27/2023
Notepad++ v8.5,XML 工具插件 -> XSL 转换。找不到太多关于它的文档,但如果它支持 XSLT 1.0,它应该支持读取外部文件。如果可以在另一个系统上尝试,我会尝试这个。感谢您查看此内容。