将 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
}
)
我有 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
}
)