【问题标题】:Camel with XSLT 2.0 and xsl:result-document keeping files in route destinationCamel 与 XSLT 2.0 和 xsl:result-document 将文件保存在路由目的地
【发布时间】:2019-08-05 16:12:40
【问题描述】:

我正在尝试使用 XSLT 2.0 转换根据项目组将 XML 文件拆分为更小的文件。为了执行转换,我使用了骆驼路线。我的问题是,当运行 xslt 转换时,生成的文件会保存在路径“外部”。

因此,例如,给定以下骆驼路线:

from("{{input.endpoint}}")
.to("xslt:xslts/ics/MappingMapTostudents.xslt?saxon=true")
.to("{{output.endpoint}}");

我希望在 {output.endpoint} 文件夹中创建生成的 xml 文件。不幸的是,saxon 将文件保存在可执行文件(camel 应用程序)所在的根文件夹中。如何将保存到 {{output.endpoint}} 或更好的文件传递到以下端点?

以下 XML 示例:

<?xml version="1.0" encoding="UTF-8"?>
<class> 
    <students>
        <student>
            <firstname>Albert</firstname> 
            <group>A</group>
        </student> 
        <student> 
            <firstname>Isaac</firstname> 
            <group>A</group>
        </student> 
        <student> 
            <firstname>Leonardo</firstname> 
            <group>B</group>
        </student> 
        <student>
            <firstname>Enrico</firstname> 
            <group>B</group>
        </student> 
        <student> 
            <firstname>Marie</firstname> 
            <group>C</group>
        </student> 
        <student> 
            <firstname>Rosalind</firstname> 
            <group>C</group>
        </student>
        <student> 
            <firstname>Ada</firstname> 
            <group>D</group>
        </student>
    </students>
</class>

XSLT 转换:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:grp="http://www.altova.com/Mapforce/grouping" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="grp xs fn">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:function name="grp:var2_function">
        <xsl:param name="var1_param" as="node()"/>
        <xsl:for-each select="$var1_param/student">
            <xsl:sequence select="fn:string(group)"/>
        </xsl:for-each>
    </xsl:function>
    <xsl:template match="/">
        <xsl:for-each-group select="class/students" group-by="grp:var2_function(.)">
            <xsl:variable name="var3_resultof_grouping_key" as="xs:string" select="current-grouping-key()"/>
            <xsl:result-document href="{fn:concat($var3_resultof_grouping_key, '.xml ')}" encoding="UTF-8">
                <class>
                    <xsl:for-each select="(current-group()/student)[(fn:string(group) = $var3_resultof_grouping_key)]">
                        <students>
                            <student>
                                <firstname>
                                    <xsl:sequence select="fn:string(firstname)"/>
                                </firstname>
                                <group>
                                    <xsl:sequence select="$var3_resultof_grouping_key"/>
                                </group>
                            </student>
                        </students>
                    </xsl:for-each>
                </class>
            </xsl:result-document>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

【问题讨论】:

  • 我不知道 Saxon 与 Apache Camel 的集成,我认为这是将文件放在所需位置的关键,但至于你的样式表,整个代码相当复杂,你可以将分组减少到&lt;xsl:for-each-group select="class/students/student" group-by="group"&gt;&lt;xsl:result-document href="{current-grouping-key()}.xml"&gt;&lt;class&gt;&lt;students&gt;&lt;xsl:copy-of select="current-group()"/&gt;&lt;/students&gt;&lt;/class&gt;&lt;/xsl:result-document&gt;&lt;/xsl:for-each-group&gt;
  • 嗨,马丁,谢谢。 xslt 文件是使用 altova MapForce 生成的,它只是一个概念证明。我真正的 xslt 要复杂得多。

标签: xslt apache-camel saxon


【解决方案1】:

您可以尝试强制输出“文件”类型。

to("xslt:xslts/ics/MappingMapTostudents.xslt?saxon=true&output=file")

然后,正如文档解释的那样,您必须使用所需的目标文件路径填充 Camel 标头:

对于 file,您必须在 IN 标头中使用键指定文件名 Exchange.XSLT_FILE_NAME 也是 CamelXsltFileName。此外,任何指向文件名的路径都必须事先创建,否则在运行时会引发异常。

祝你好运

【讨论】:

    【解决方案2】:

    我对 Apache-Camel 知之甚少,不幸的是有关 StackOverflow 技术的问题似乎没有很高的成功率。

    http://camel.apache.org/xslt.html 的文档没有提供有关如何设置基本输出 URI 的任何线索,Saxon 使用它来解析出现在 xsl:result-document/@href 中的任何相对 URI。

    想到的最简单的方法是给转换传递一个参数,其值为输出目录的绝对路径:

    <xsl:param name="outDir" as="xs:string"/>
    ...
    <xsl:result-document 
       href="file:///{$outDir}{$var3_resultof_grouping_key}.xml"/>
    

    但了解 Apache Camel 的人可能会提出更优雅的解决方案。

    【讨论】:

    • 谢谢迈克尔。这就是我已经做的一种解决方法,但它是一个丑陋的解决方案,因为它打破了我的骆驼路线并迫使我将它分成两部分。
    猜你喜欢
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    相关资源
    最近更新 更多