如何将多个xslt文件和xml文件合并为另一个输入以获得最终输出?

时间:2016-11-29 10:31:13

标签: xml xslt xslt-1.0 xslt-2.0

我有三个xsl文件和一个输入文件:

-input.xml process1.xsl output1.xml
-output1.xml process2.xsl output3.xml

现在我想把它作为:

input.xml process.xslt output.xml

process1.xsl,process2.xsl及其输出应该作为传递 输入到xsl文件并在相同的process.xsl文件中生成output.xml。

我如何在xslt中执行此操作,我已经引用了xslt apply imports但是我没有得到正确的引用来将xml输出作为另一个xsl文件的输入分配到一个xsl ..任何人都可以帮助我吗?

这里我调用了input.xml并使用了process1.xsl作为第一步 并且生成的输出存储在$ content变量中,现在我被困在这里,如何导入process2.xsl并将其分配给变量$ content中的先前输出,我只能显示其输出我想要它到下一个xsl文件:

<xsl:import href="process1.xsl"/>

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



<xsl:template match="/">

 <xsl:variable name="content">
    <xsl:apply-imports/>
 </xsl:variable>

<xsl:apply-templates select="exsl:node-set($content)/*" mode="m"/>
</xsl:template>

<xsl:template match="@*|*|text()" mode="m">

<xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="@*|*|text()" mode="m"/>
</xsl:copy>

</xsl:template>

类似的东西,但这不起作用?

1 个答案:

答案 0 :(得分:0)

使用XSLT 3.0,您可以使用fold-left函数(https://www.w3.org/TR/xpath-functions-31/#func-fold-left)和transform函数(https://www.w3.org/TR/xpath-functions-31/#func-transform)来链接转换:

<xsl:stylesheet
 version="3.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="fn xs">

 <xsl:param name="sheet-uris" as="xs:string*" select="'process1.xsl', 'process2.xsl'"/>

 <xsl:param name="input-uri" as="xs:string" select="'input.xml'"/>
 <xsl:param name="input-doc" as="document-node()" select="doc($input-uri)"/>

 <xsl:mode on-no-match="shallow-copy"/>

 <xsl:template name="xsl:initial-template">
    <xsl:apply-templates select="fold-left($sheet-uris, $input-doc, function($input, $sheet-uri) { transform(map { 'stylesheet-location' : $sheet-uri, 'source-node' : $input })?output })"/>
 </xsl:template>

 <xsl:template match="/*">
     <xsl:comment select="'Processed by ' || document-uri(document(''))"/>
     <xsl:next-match/>
 </xsl:template>

</xsl:stylesheet>

显然,在真正的转换中,样式表不仅仅是输出注释来指示它处理输入,而是使用上面的Saxon 9.7 EE和-it -xsl:process.xsl调用的样式表,其中输入是

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <foo>bar</foo>
</root>

并且两个样式表process1.xslprocess2.xsl例如是

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.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" xmlns:math="http://www.w3.org/2005/xpath-functions/math" xmlns:array="http://www.w3.org/2005/xpath-functions/array" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:xhtml="http://www.w3.org/1999/xhtml" exclude-result-prefixes="array fn map math xhtml xs">

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:template match="/*">
        <xsl:comment select="'Processed by ' || document-uri(document(''))"/>
        <xsl:next-match/>
    </xsl:template>

</xsl:stylesheet>

输出

<?xml version="1.0" encoding="UTF-8"?><!--Processed by file:/SomePath/process1.xsl--><!--Processed by file:/SomePath/process2.xsl--><!--Processed by file:/SomePath/process.xsl--><root>
    <foo>bar</foo>
</root>

所以链接正在发挥作用。

您可以将输入文档作为主要输入-s并将主样式表更改为

,而不是将输入文档作为参数传递
<xsl:stylesheet
 version="3.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="fn xs">

 <xsl:param name="sheet-uris" as="xs:string*" select="'process1.xsl', 'process2.xsl'"/>

 <xsl:mode on-no-match="shallow-copy"/>

 <xsl:template match="/">
    <xsl:apply-templates select="fold-left($sheet-uris, ., function($input, $sheet-uri) { transform(map { 'stylesheet-location' : $sheet-uri, 'source-node' : $input })?output })/node()"/>
 </xsl:template>

 <xsl:template match="/*">
     <xsl:comment select="'Processed by ' || document-uri(document(''))"/>
     <xsl:next-match/>
 </xsl:template>

</xsl:stylesheet>

如果您想使用Java链转换,请参阅https://stackoverflow.com/a/35845231/252228以获取示例。