以下XSLT完成了将输入转换为在Stylus Studio上无缝输出的工作:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" exclude-result-prefixes="xs"/>
<xsl:strip-space elements="*"/>
<xsl:param name="COEP_FilePath"/>
<xsl:template name="main>
<xsl:element name="actualUpload" exclude-result-prefixes="xs">
<xsl:choose>
<xsl:when test="(not($COEP_FilePath) and not(string($COEP_FilePath)))">
<xsl:message terminate="yes">One or more Input Parameter(s) not supplied!</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="COEPData" select="unparsed-text($COEP_FilePath)"/>
<xsl:variable name="Tokenized_COEPData" select="tokenize($COEPData, '\r\n')"/>
<xsl:variable name="Period" select="normalize-space(tokenize(tokenize($COEPData, '\r\n')[1], '~')[3])"/>
<xsl:variable name="FiscalYear" select="normalize-space(tokenize(tokenize($COEPData, '\r\n')[1], '~')[6])"/>
<xsl:variable name="Orders" as="element(Orders)*" exclude-result-prefixes="xs">
<Orders>
<xsl:for-each select="$Tokenized_COEPData">
<xsl:variable name="valueInContext" select="tokenize(., '~')"/>
<Order>
<!--<period>
<xsl:value-of select="normalize-space($valueInContext[3])"/>
</period>
<finYear>
<xsl:value-of select="normalize-space($valueInContext[6])"/>
</finYear>
<actualRecId>
<xsl:value-of select="normalize-space($valueInContext[2])"/>
</actualRecId>-->
<cur>
<xsl:value-of select="normalize-space($valueInContext[9])"/>
</cur>
<amount>
<xsl:value-of select="if (ends-with(normalize-space($valueInContext[4]), '-')) then concat('-', substring-before(normalize-space($valueInContext[4]), '-')) else normalize-space($valueInContext[4])"/>
</amount>
<internalOrderNum>
<xsl:value-of select="normalize-space($valueInContext[5])"/>
</internalOrderNum>
</Order>
</xsl:for-each>
</Orders>
</xsl:variable>
<period>
<xsl:value-of select="$Period"/>
</period>
<finYear>
<xsl:value-of select="$FiscalYear"/>
</finYear>
<actuals>
<xsl:for-each-group select="$Orders/*" group-by="concat(internalOrderNum, '|', cur)">
<actualRec id="{internalOrderNum}">
<cur>
<xsl:value-of select="cur"/>
</cur>
<amount>
<xsl:value-of select="sum(current-group()/xs:decimal(amount))"/>
</amount>
</actualRec>
</xsl:for-each-group>
</actuals>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
为此,我必须在Stylus Studio的“方案属性/处理器”部分中将初始模板值指定为main。 XSLT将用在Java应用程序中(使用Saxon HE 9.5.1-2库的iWay Service Manager),并且我无法找到指定初始模板的方法。也许有一个我可以利用的JVM选项,但是我正在Internet上查找,还没有点击。
同时,我尝试解决将用户定义的模板名称“ main”替换为“ xsl:initial-template”的问题,但并未注意到此提要可用于其他SO讨论,因此没有得到证明成功。甚至在Stylus Studio中也不是,因为它也使用了较旧版本的Saxon lib。我意识到所使用的Saxon HE库需要升级到最新的维护版本。但是,这样做将对Java应用程序产生更广泛的影响,因为我们必须对现有解决方案/等进行回归测试。
为了节省时间,我只想探讨以下两个选项:
1)使用显然可以指定初始模板名称的配置文件。虽然我需要一些有关如何在Java应用程序上启用此功能的建议;
2)建议重写XSLT,以免由于使用unparsed-text()函数而导致XSLT不会解析错误;
关于它的价值,这里是一个示例输入:
1000~1234567890~007~ 12345.05-~ORDUMMYORD1 ~2019~A~04~EUR ~ ~0212~
1000~0987654321~007~ 12345.05~ORDUMMYORD1 ~2019~S~04~EUR ~ABCDEFGHIJ~0212~
1000~6789054321~007~ 20-~ORDUMMYORD3 ~2019~A~04~EUR ~ ~0184~
及其对应的输出:
<?xml version='1.0' encoding='UTF-8' ?>
<actualUpload>
<period>007</period>
<finYear>2019</finYear>
<actuals>
<actualRec id="ORDUMMYORD1">
<cur>EUR</cur>
<amount>0</amount>
</actualRec>
<actualRec id="ORDUMMYORD3">
<cur>EUR</cur>
<amount>-20</amount>
</actualRec>
</actuals>
</actualUpload>
请提出建议。谢谢。
EDIT 1:13:39 CET
我将XSLT修改为以下解决问题的方法:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" exclude-result-prefixes="xs"/>
<xsl:strip-space elements="*"/>
<xsl:param name="COEP_FilePath"/>
<xsl:template match="/">
<xsl:element name="actualUpload" exclude-result-prefixes="xs">
<xsl:choose>
<xsl:when test="(not($COEP_FilePath) and not(string($COEP_FilePath)))">
<xsl:message terminate="yes">One or more Input Parameter(s) not supplied!</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="COEPData">
<root>
<xsl:value-of select="unparsed-text($COEP_FilePath)"/>
</root>
</xsl:variable>
<xsl:variable name="Tokenized_COEPData" select="tokenize($COEPData/root, '\r\n')"/>
<xsl:variable name="Period" select="normalize-space(tokenize(tokenize($COEPData/root, '\r\n')[1], '~')[3])"/>
<xsl:variable name="FiscalYear" select="normalize-space(tokenize(tokenize($COEPData/root, '\r\n')[1], '~')[6])"/>
<xsl:variable name="Orders" as="element(Orders)*" exclude-result-prefixes="xs">
<Orders>
<xsl:for-each select="$Tokenized_COEPData">
<xsl:variable name="valueInContext" select="tokenize(., '~')"/>
<Order>
<!--<period>
<xsl:value-of select="normalize-space($valueInContext[3])"/>
</period>
<finYear>
<xsl:value-of select="normalize-space($valueInContext[6])"/>
</finYear>
<actualRecId>
<xsl:value-of select="normalize-space($valueInContext[2])"/>
</actualRecId>-->
<cur>
<xsl:value-of select="normalize-space($valueInContext[9])"/>
</cur>
<amount>
<xsl:value-of select="if (ends-with(normalize-space($valueInContext[4]), '-')) then concat('-', substring-before(normalize-space($valueInContext[4]), '-')) else normalize-space($valueInContext[4])"/>
</amount>
<internalOrderNum>
<xsl:value-of select="normalize-space($valueInContext[5])"/>
</internalOrderNum>
</Order>
</xsl:for-each>
</Orders>
</xsl:variable>
<period>
<xsl:value-of select="$Period"/>
</period>
<finYear>
<xsl:value-of select="$FiscalYear"/>
</finYear>
<actuals>
<xsl:for-each-group select="$Orders/*" group-by="concat(internalOrderNum, '|', cur)">
<actualRec id="{internalOrderNum}">
<cur>
<xsl:value-of select="cur"/>
</cur>
<amount>
<xsl:value-of select="sum(current-group()/xs:decimal(amount))"/>
</amount>
</actualRec>
</xsl:for-each-group>
</actuals>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
但是如果对以下内容进行评论,那会很好。谢谢。
1)使用显然可以指定初始模板名称的配置文件。虽然我需要一些有关如何在Java应用程序上启用此功能的建议;
添加功能XSLT以供参考。变量COEPData
现在在unparsed-text()周围有一个XML标签,从而允许处理器继续操作。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" exclude-result-prefixes="xs"/>
<xsl:strip-space elements="*"/>
<xsl:param name="COEP_FilePath"/>
<xsl:template match="/">
<xsl:element name="actualUpload" exclude-result-prefixes="xs">
<xsl:choose>
<xsl:when test="(not($COEP_FilePath) and not(string($COEP_FilePath)))">
<xsl:message terminate="yes">One or more Input Parameter(s) not supplied!</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="COEPData">
<root>
<xsl:value-of select="unparsed-text($COEP_FilePath)"/>
</root>
</xsl:variable>
<xsl:variable name="Tokenized_COEPData" select="tokenize($COEPData/root, '\r\n')"/>
<xsl:variable name="Period" select="normalize-space(tokenize(tokenize($COEPData/root, '\r\n')[1], '~')[3])"/>
<xsl:variable name="FiscalYear" select="normalize-space(tokenize(tokenize($COEPData/root, '\r\n')[1], '~')[6])"/>
<xsl:variable name="Orders" as="element(Orders)*" exclude-result-prefixes="xs">
<Orders>
<xsl:for-each select="$Tokenized_COEPData">
<xsl:variable name="valueInContext" select="tokenize(., '~')"/>
<Order>
<!--<period>
<xsl:value-of select="normalize-space($valueInContext[3])"/>
</period>
<finYear>
<xsl:value-of select="normalize-space($valueInContext[6])"/>
</finYear>
<actualRecId>
<xsl:value-of select="normalize-space($valueInContext[2])"/>
</actualRecId>-->
<cur>
<xsl:value-of select="normalize-space($valueInContext[9])"/>
</cur>
<amount>
<xsl:value-of select="if (ends-with(normalize-space($valueInContext[4]), '-')) then concat('-', substring-before(normalize-space($valueInContext[4]), '-')) else normalize-space($valueInContext[4])"/>
</amount>
<internalOrderNum>
<xsl:value-of select="normalize-space($valueInContext[5])"/>
</internalOrderNum>
</Order>
</xsl:for-each>
</Orders>
</xsl:variable>
<period>
<xsl:value-of select="$Period"/>
</period>
<finYear>
<xsl:value-of select="$FiscalYear"/>
</finYear>
<actuals>
<xsl:for-each-group select="$Orders/*" group-by="concat(internalOrderNum, '|', cur)">
<actualRec id="{internalOrderNum}">
<cur>
<xsl:value-of select="cur"/>
</cur>
<amount>
<xsl:value-of select="sum(current-group()/xs:decimal(amount))"/>
</amount>
</actualRec>
</xsl:for-each-group>
</actuals>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:template>
</xsl:stylesheet>