how do i merge multiple xslt files and xml files t

2019-07-29 10:24发布

I have three xsl files and one input file:

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

now i want to just have it as:

input.xml process.xslt output.xml

process1.xsl, process2.xsl and their outputs should passed as the input to the xsl file and generate output.xml in the same process.xsl file.

how do i do this in xslt , i have referred to xslt apply imports but i am not getting proper reference for assigning the xml output as input for another xsl file all in one xsl.. can anyone help me out?

here i have invoked the input.xml and used process1.xsl for first step and the output generated is stored in the $content variable now i am stuck here that how do i import the process2.xsl and assing it to the previous output in variable $content, i am just able to display its output i want to assing it to next xsl file:

<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>

something like this but this does not work?

1条回答
聊天终结者
2楼-- · 2019-07-29 10:33

Using XSLT 3.0 you could use the fold-left function (https://www.w3.org/TR/xpath-functions-31/#func-fold-left) together with the transform function (https://www.w3.org/TR/xpath-functions-31/#func-transform) to chain the transformations:

<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>

Obviously in a real transformation your stylesheet would do more than outputting a comment to indicate its processing the input but using above stylesheet called with Saxon 9.7 EE and -it -xsl:process.xsl, where the input is

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

and the two stylesheets process1.xsl and process2.xsl are for instance

<?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>

the output is

<?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>

so the chaining is working.

Instead of passing the input document as a parameter you could also provide it as the primary input -s and change the main stylesheet to

<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>

If you want to chain transformations with Java then see https://stackoverflow.com/a/35845231/252228 for an example.

查看更多
登录 后发表回答