将 2 个 xslt 组合成一个

Combine 2 xslt into a single one

我有 2 个 xslt。两者都一个接一个地工作得很好。有什么方法可以将 2 个 xslt 合并为一个吗?

第一个 xslt 使用累加器进行查找:

<?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:map="http://www.w3.org/2005/xpath-functions/map"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:wd="urn:com.workday/bsvc"
        xmlns:ws="urn:com.workday/workersync"
        exclude-result-prefixes ="wd map xs ws"
        version="3.0">           
        <xsl:mode streamable="yes" on-no-match="shallow-skip" use-accumulators="CompanyLookup CurrentLookupValue"/>            
        <xsl:output method="xml" indent="yes"/>        
        
        <xsl:accumulator name="CurrentLookupValue" as="xs:string" initial-value="''" streamable="yes">
            <xsl:accumulator-rule match="wd:Employee_ID/text()" select="."/>
        </xsl:accumulator>
                
        <xsl:accumulator name="CompanyLookup" as="map(xs:string,xs:string)" initial-value="map{}" streamable="yes">
            <xsl:accumulator-rule match="wd:Company/text()" select="map:put($value, accumulator-before('CurrentLookupValue'),string(.))"/>
        </xsl:accumulator>     
        
        <xsl:template match="root/row" mode="report-in-mem">      
            <row>
                <xsl:variable name="company" select="accumulator-before('CompanyLookup')( normalize-space( employee_id ) )"/>                       
                <employeeID><xsl:value-of select="employee_id"/></employeeID>
                <company><xsl:value-of select="$company"/></company>
                <State><xsl:value-of select="State" /></State>
                <Work_days><xsl:value-of select="work_days"/></Work_days> 
            </row>       
        </xsl:template>
    </xsl:stylesheet>

第二个 XSLT 正在根据 employeeID 对第一个 xslt 的输出进行分组:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" version="3.0">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="root">
        <root>
            <xsl:for-each-group select="row" group-by="employeeID">
                <row>
                    <employee_id><xsl:value-of select="employeeID" /></employee_id>
                    <company><xsl:value-of select="company"/></company>                 
                    <xsl:for-each select="current-group()">                            
                        <Data> 
                            <State><xsl:value-of select="State" /></State>
                            <Work_days><xsl:value-of select="Work_days"/></Work_days>
                        </Data> 
                    </xsl:for-each>
                </row>    
            </xsl:for-each-group>
        </root>
    </xsl:template>
</xsl:stylesheet>

输入 XML 是来自两个来源的聚合数据:

<?xml version="1.0" encoding="utf-8"?>
<AggregatedData>
   <wd:Report_Data xmlns:wd="urn:com.workday/bsvc">
      <wd:Report_Entry>
         <wd:Employee_ID>xyz1</wd:Employee_ID>
         <wd:Company>ABC</wd:Company>
      </wd:Report_Entry>
      <wd:Report_Entry>
         <wd:Employee_ID>xyz2</wd:Employee_ID>
         <wd:Company>ABC</wd:Company>
      </wd:Report_Entry>
   </wd:Report_Data>
<root>
    <row>
        <employee_id>xyz2</employee_id>
        <State>TX</State>
        <work_days>0</work_days>
    </row>
    <row>
        <employee_id>xyz2</employee_id>
        <State>CA</State>
        <work_days>10</work_days>
    </row>

</root>
</AggregatedData>

最终输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <row>
      <employee_id>xyz2</employee_id>
      <company>ABC</company>
      <Data>
         <State>TX</State>
         <Work_days>0</Work_days>
      </Data>
      <Data>
         <State>CA</State>
         <Work_days>10</Work_days>
      </Data>
   </row>
</root>

有些元素名称在拼写或字母大小写方面似乎有所不同,但忽略流式处理这两个 XSLT 的融合是相似的

<xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:map="http://www.w3.org/2005/xpath-functions/map"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:wd="urn:com.workday/bsvc"
        xmlns:ws="urn:com.workday/workersync"
        exclude-result-prefixes ="wd map xs ws"
        version="3.0">           
        <xsl:mode streamable="yes" on-no-match="shallow-skip" use-accumulators="CompanyLookup CurrentLookupValue"/>            
        <xsl:output method="xml" indent="yes"/>        
        
        <xsl:accumulator name="CurrentLookupValue" as="xs:string" initial-value="''" streamable="yes">
            <xsl:accumulator-rule match="wd:Employee_ID/text()" select="."/>
        </xsl:accumulator>
                
        <xsl:accumulator name="CompanyLookup" as="map(xs:string,xs:string)" initial-value="map{}" streamable="yes">
            <xsl:accumulator-rule match="wd:Company/text()" select="map:put($value, accumulator-before('CurrentLookupValue'),string(.))"/>
        </xsl:accumulator>     
        
   <xsl:template match="root">
        <root>
            <xsl:for-each-group select="row" group-by="employee_id">
                <row>
                    <employee_id><xsl:value-of select="employee_id" /></employee_id>
                    <company><xsl:value-of select="accumulator-before('CompanyLookup')(employee_id)"/></company>                 
                    <xsl:for-each select="current-group()">                            
                        <Data> 
                            <State><xsl:value-of select="State" /></State>
                            <Work_days><xsl:value-of select="work_days"/></Work_days>
                        </Data> 
                    </xsl:for-each>
                </row>    
            </xsl:for-each-group>
        </root>
    </xsl:template>
</xsl:stylesheet> 

就使用 fn:transform 和 XPath 3 链接一系列 XSLT 而言,您可以使用例如

let $xslts := ($xslt1, $xslt2)
return
    fold-left(
        $xslts, 
        ., 
        function($source, $xslt) { 
            transform(
                map { 
                    'source-node' : $source, 
                    'stylesheet-node' : $xslt 
                }
            )?output 
        }
    )