有没有一种方法可以合并多个XSLT以在单个输出文件中获得输出



我目前有一个开发项目,它从一个XML输入中生成三个不同的文件,代表三种不同的员工状态。以下是示例XML。

<wd:Report_Data xmlns:wd="urn:com.workday.report/Demo_Report">
<wd:Report_Entry>
<wd:Flag>HIRE</wd:Flag>
<wd:Userid>12345</wd:Userid>
<wd:FirstName>Jack</wd:FirstName>
<wd:LastName>Jones</wd:LastName>
<wd:BusinessTitle>Engineer</wd:businessTitle>
<wd:Country>US</wd:Country>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Flag>UPDATE</wd:Flag>
<wd:Userid>890767</wd:Userid>
<wd:FirstName>Mike</wd:FirstName>
<wd:LastName>Balder</wd:LastName>
<wd:BusinessTitle>Jr.Engineer</wd:businessTitle>
<wd:Country>US</wd:Country>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Flag>TERMINATE</wd:Flag>
<wd:Userid>543908</wd:Userid>
<wd:FirstName>Bolton</wd:FirstName>
<wd:LastName>James</wd:LastName>
<wd:BusinessTitle>Sr.Engineer</wd:businessTitle>
<wd:Country>US</wd:Country>
</wd:Report_Entry>
</wd:Report_Data>

我有以下三个XSLT,它们生成了三个不同员工状态的文件,如下所示。

XSLT 1

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" 
xmlns:xtt="urn:com.workday/xtt" xmlns:wd="urn:com.workday.report/Demo_Report" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
<xsl:output method="text"/>
<xsl:variable name="linefeed" select="'&#xA;'"/>
<xsl:template match="wd:Report_Data">
<File>
<xsl:text>user,add,abc@y.com,admin,ghy567</xsl:text>
<xsl:value-of select="$linefeed"/>
<xsl:text>"User id","FirstName","LastName","BusinessTitle","Country"</xsl:text>
<xsl:value-of select="$linefeed"/>
<!--  for each Employee section -->
<xsl:for-each select="/wd:Report_Data/wd:Report_Entry">
<xsl:if test="wd:Flag ='HIRE' and wd:Position Type !=''">
<xsl:text>"</xsl:text>
<xsl:value-of select="wd:Userid"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:FirstName"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:LastName"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:BusinessTitle"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:Country"/>
</xsl:if>
</xsl:for-each>
</File>
</xsl:template>
</xsl:stylesheet>

XSLT 2

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" 
xmlns:xtt="urn:com.workday/xtt" xmlns:wd="urn:com.workday.report/Demo_Report" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
<xsl:output method="text"/>
<xsl:variable name="linefeed" select="'&#xA;'"/>
<xsl:template match="wd:Report_Data">
<File>
<xsl:text>user,update,abc@y.com,admin,ghy567</xsl:text>
<xsl:value-of select="$linefeed"/>
<xsl:text>"User id","FirstName","LastName","BusinessTitle","Country"</xsl:text>
<xsl:value-of select="$linefeed"/>
<!--  for each Employee section -->
<xsl:for-each select="/wd:Report_Data/wd:Report_Entry">
<xsl:if test="wd:Flag ='UPDATE' and wd:Position Type !=''">
<xsl:text>"</xsl:text>
<xsl:value-of select="wd:Userid"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:FirstName"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:LastName"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:BusinessTitle"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:Country"/>
</xsl:if>
</xsl:for-each>
</File>
</xsl:template>
</xsl:stylesheet>

XSLT 3

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" 
xmlns:xtt="urn:com.workday/xtt" xmlns:wd="urn:com.workday.report/Demo_Report" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
<xsl:output method="text"/>
<xsl:variable name="linefeed" select="'&#xA;'"/>
<xsl:template match="wd:Report_Data">
<File>
<xsl:text>user,terminate,abc@y.com,admin,ghy567</xsl:text>
<xsl:value-of select="$linefeed"/>
<xsl:text>"User id","FirstName","LastName","BusinessTitle","Country"</xsl:text>
<xsl:value-of select="$linefeed"/>
<!--  for each Employee section -->
<xsl:for-each select="/wd:Report_Data/wd:Report_Entry">
<xsl:if test="wd:Flag ='TERMINATE' and wd:Position Type !=''">
<xsl:text>"</xsl:text>
<xsl:value-of select="wd:Userid"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:FirstName"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:LastName"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:BusinessTitle"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:Country"/>
</xsl:if>
</xsl:for-each>
</File>
</xsl:template>
</xsl:stylesheet>

输出文件1

用户,添加,abc@y.com,admin,ghy567
用户id,名字,姓氏,企业名称,国家
12345,Jack,Jones,工程师,美国

输出文件2

用户,更新,abc@y.com,admin,ghy567
用户名,姓氏,企业名称,国家
890767,Mike,Balder,Jr.Engineer,美国

输出文件3

用户,终止,abc@y.com,admin,ghy567
用户名,姓氏,企业名称,国家
543908,Bolton,James,美国高级工程师

现在,我有另一个要求,即第四个文件必须由单个文件中所有三个文件的所有合并数据生成,如下所示。

用户,添加,abc@y.com,admin,ghy567
用户id,名字,姓氏,企业名称,国家
12345,Jack,Jones,工程师,美国

用户,更新,abc@y.com,admin,ghy567
用户名,姓氏,企业名称,国家
890767,Mike,Balder,Jr.Engineer,美国

用户,终止,abc@y.com,admin,ghy567
用户名,姓氏,企业名称,国家
543908,Bolton,James,美国高级工程师

那么,有没有一种方法可以将三个XSLT合并到一个文件中以获得输出呢?

使用XSLT3或XQuery3.1,您可以使用fn:transform从XPath运行XSLT,因此在XQuery3.1中可以使用例如

declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method 'text';
declare option output:item-separator '&#10;&#10;';
declare variable $sheet-uris as xs:string* external := ('sheet1.xsl', 'sheet2.xsl', 'sheet3.xsl');
declare variable $sheets as document-node()* external :=  $sheet-uris ! doc(.);
let $xml := .
return
$sheets 
! 
transform(
map {
'stylesheet-node' : .,
'source-node' : $xml,
'delivery-format' : 'serialized'
}
)?output

或XSLT 3

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:param name="sheet-uris" as="xs:string*" select="'sheet1.xsl', 'sheet2.xsl', 'sheet3.xsl'"/>
<xsl:param name="$sheets" as="document-node()*" select="$sheet-uris ! doc(.)"/>
<xsl:output method="text" item-separator="&#10;&#10;"/>
<xsl:template match="/">
<xsl:sequence
select="
$sheets 
! 
transform(
map {
'stylesheet-node' : .,
'source-node' : current(),
'delivery-format' : 'serialized'
}
)?output"/>
</xsl:template>

</xsl:stylesheet>

以下是如何在XProc 3中实现这一点(目前由Morgana XProc III测试版支持,记录在https://www.xml-project.com/files/doc/manual.html):

<p:declare-step name="concat" xmlns:p="http://www.w3.org/ns/xproc" version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-inline-prefixes="#all">
<p:input port="source"/>
<p:option name="sheet-uris" as="xs:string*" select="'sheet1.xsl', 'sheet2.xsl', 'sheet3.xsl'"/>
<p:output port="result" sequence="true" serialization="map { 'method' : 'text', 'item-separator' : '&#10;' }"/>
<p:for-each>
<p:with-input select="$sheet-uris"/>
<p:xslt>
<p:with-input port="source" pipe="source@concat"/>
<p:with-input port="stylesheet" href="{.}"/>
</p:xslt>
</p:for-each>
</p:declare-step>

它使用XProc内置的p:for-each步骤https://spec.xproc.org/master/head/xproc/#p.for-每个与CCD_ 3步骤一起https://spec.xproc.org/master/head/steps/#c.xslt以根据作为sheet-uris选项提供的样式表序列运行输入源。

怎么样:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wd="urn:com.workday.report/Demo_Report">
<xsl:output method="text"/>
<xsl:variable name="header2" select="'User id,FirstName,LastName,BusinessTitle,Country&#xA;'"/>
<xsl:template match="/wd:Report_Data">
<!--  ADD -->
<xsl:text>user,add,abc@y.com,admin,ghy567&#xA;</xsl:text>
<xsl:value-of select="$header2"/>
<xsl:apply-templates select="wd:Report_Entry[wd:Flag='HIRE']"/>
<xsl:text>&#xA;</xsl:text>
<!--  UPDATE -->
<xsl:text>user,update,abc@y.com,admin,ghy567&#xA;</xsl:text>
<xsl:value-of select="$header2"/>
<xsl:apply-templates select="wd:Report_Entry[wd:Flag='UPDATE']"/>
<xsl:text>&#xA;</xsl:text>
<!--  TERMINATE -->
<xsl:text>user,terminate,abc@y.com,admin,ghy567&#xA;</xsl:text>
<xsl:value-of select="$header2"/>
<xsl:apply-templates select="wd:Report_Entry[wd:Flag='TERMINATE']"/>
</xsl:template>

<xsl:template match="wd:Report_Entry">
<xsl:text>"</xsl:text>
<xsl:value-of select="wd:Userid"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:FirstName"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:LastName"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:BusinessTitle"/>
<xsl:text>","</xsl:text>
<xsl:value-of select="wd:Country"/>
<xsl:text>"&#xA;</xsl:text>
</xsl:template>
</xsl:stylesheet>

相关内容

  • 没有找到相关文章

最新更新