【问题标题】:Merging two list with xslt用 xslt 合并两个列表
【发布时间】:2016-03-21 16:43:51
【问题描述】:

基本上我需要组合来自两个不同 xslt 转换的输出。

我正在使用“container.xslt”来导入和组合两个内部xslt:“transform1.xslt”和“transform2.xslt”

这两个转换文件是由 xslt 工具程序生成的,所以我想避免对它们进行更改。

这是我的输入 xml:

<Enrollments>
    <Enrollment>
        <MEDICAL id="11111111">
        </MEDICAL>
    </Enrollment>
</Enrollments>

这是我目前得到的输出:

<fields>
    <fields>
        <field name="ID1">
            <value>11111111</value>
        </field>
    </fields>
    <fields>
        <field name="ID2">
            <value>11111111</value>
        </field>
    </fields>
</fields>

这是我正在寻找的输出:

<fields>
    <field name="ID1">
        <value>11111111</value>
    </field>
    <field name="ID2">
        <value>11111111</value>
    </field>
</fields>

container.xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="xs fn">

    <xsl:include href="./transform1.xslt"/>
    <xsl:include href="./transform2.xslt"/>

    <xsl:output method="xml" encoding="UTF-8" byte-order-mark="no" indent="yes"/>

    <xsl:variable name="list1">
        <xsl:call-template name="one" />
    </xsl:variable>

    <xsl:param name="list2">
        <xsl:call-template name="two"/>
    </xsl:param>

    <xsl:template name="mergedList" match="/">
        <fields>
            <xsl:copy-of select="$list1" />
            <xsl:copy-of select="$list2" />
        </fields>
    </xsl:template>

</xsl:stylesheet>

transform1.xslt

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn">
        <xsl:output method="xml" encoding="UTF-8" byte-order-mark="no" indent="yes"/>
        <xsl:template match="/" name="one">
            <fields>
                <field>
                    <xsl:attribute name="name" select="'ID1'"/>
                    <xsl:for-each select="Enrollments/Enrollment/MEDICAL">
                        <value>
                            <xsl:sequence select="fn:string(@id)"/>
                        </value>
                    </xsl:for-each>
                </field>
            </fields>
        </xsl:template>
    </xsl:stylesheet>

transform2.xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn">
    <xsl:output method="xml" encoding="UTF-8" byte-order-mark="no" indent="yes"/>
    <xsl:template match="/" name="two">
        <fields>
            <field>
                <xsl:attribute name="name" select="'ID2'"/>
                <xsl:for-each select="Enrollments/Enrollment/MEDICAL">
                    <value>
                        <xsl:sequence select="fn:string(@id)"/>
                    </value>
                </xsl:for-each>
            </field>
        </fields>
    </xsl:template>
</xsl:stylesheet>

它可能完全属于另一个问题,但如果有人有建议,我会在这里添加它。我必须将这两行添加到我的转换文件中,以允许我在 container.xslt 中使用命名模板。最好避免更改导入的 xlst

<xsl:attribute name="name" select="'ID1'"/>

<xsl:attribute name="name" select="'ID2'"/>

提前感谢您的任何建议!我对 xslt 还很陌生,手写的东西不多。

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    可以这么简单吗

    <xsl:template name="mergedList" match="/">
        <fields>
            <xsl:copy-of select="$list1/fields/field" />
            <xsl:copy-of select="$list2/fields/field" />
        </fields>
    </xsl:template>
    

    ?


    旧版答案

    <Enrollments>
        <Enrollment>
            <MEDICAL id="11111111">
            </MEDICAL>
        </Enrollment>
    </Enrollments>
    

    <fields>
        <field name="ID1">
            <value>11111111</value>
        </field>
        <field name="ID2">
            <value>11111111</value>
        </field>
    </fields>
    

    这样简单的事情就足够了:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" encoding="UTF-8" byte-order-mark="no" indent="yes"/>
    
        <xsl:template match="Enrollments">
            <fields>
                <xsl:apply-templates select="Enrollment">
                    <xsl:with-param name="name" select="'ID1'" />
                </xsl:apply-templates>
                <xsl:apply-templates select="Enrollment">
                    <xsl:with-param name="name" select="'ID2'" />
                </xsl:apply-templates>
            </fields>
        </xsl:template>
    
        <xsl:template match="Enrollment">
            <xsl:param name="name" />
            <field name="{$name}">
                <value><xsl:value-of select="MEDICAL/@id" /></value>
            </field>
        </xsl:template>
    </xsl:stylesheet>
    

    在我看来,您拥有的其他东西似乎严重过度设计。

    【讨论】:

    • 我同意它似乎过度设计。我已经相当简化了两个导入的 xslt,以使示例尽可能通用。我真的需要一种方法来运行两个 xslts 转换并组合输出。感谢您的建议,但它并没有解决我问题的根本问题。 (也许是因为我是怎么问的:-])
    • 啊。查看修改后的答案。
    • 太棒了,非常感谢!我以为这很简单。我在尝试 $list1/fields 而不是 $list1/fields/field
    • 您对如何避免使用命名模板有什么想法吗?就像我提到的,这两个导入的文件是由映射工具生成的,因此最好避免进行更改。
    • 查看旧版本的答案,让它沉入一分钟。
    猜你喜欢
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 2014-03-19
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    相关资源
    最近更新 更多