如何解决:XSLT 3.0 条件筛选 (if) 问题



for-each 循环中的"If"条件不起作用。根据输入文件和交叉引用文件中的区域代码,不需要生成某些具有特定国家/地区代码的消息。

例如,如果输入消息包含不在输入消息中的国家/地区代码 CH,则不应将有效负载生成为输出。

<?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" 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" xmlns:err="http://www.w3.org/2005/xqt-errors" exclude-result-prefixes="array fn map math xhtml xs err" version="3.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="xslt.transform.params">DE|AT|UK|IE|NL</xsl:param>
<xsl:variable name="vCountryCode">
<xsl:value-of select="$xslt.transform.params"/>
</xsl:variable>
<xsl:param name="xslt.location.uriXSLTPath">
<xsl:text>app</xsl:text>
</xsl:param>
<xsl:param name="uriXSLT">
<xsl:value-of select="$xslt.location.uriXSLTPath"/>
</xsl:param>
<xsl:variable name="vSupplierFullPath" select="string(concat($uriXSLT,'/SupplierCrossReference.xml'))"/>
<xsl:variable name="vSupplierCrossReferences" select="document($vSupplierFullPath)/*:SupplierCrossReferences"/>
<xsl:template match="/advice_file/product" name="xsl:initial-template">
<xsl:text>"warehouses": [</xsl:text>
<xsl:for-each select="warehouseBreakout/warehouse">
<xsl:variable name="vVendor" select="../../vendor"/>
<xsl:variable name="vWH" select="@warehouse-id"/>
<xsl:variable name="vReg" select="fn:copy-of($vSupplierCrossReferences/SupplierCrossReference[TraitID=$vVendor]/warehouses/warehouse[@id=$vWH])"/>
<xsl:text>{</xsl:text>
<xsl:text>"warehouseId" : "</xsl:text>
<xsl:value-of select=" fn:concat($vVendor,'-', $vWH)"/>
<xsl:text>",</xsl:text>
<xsl:text>"quantity" : </xsl:text>
<xsl:value-of select="qtyonhand"/>
<xsl:choose>
<xsl:when test="next_available/@quantity != '' and next_available/@quantity !=0 ">
<xsl:variable name="vNextDate" select="next_available/@date"/>
<xsl:text>,</xsl:text>
<xsl:text>"nextAvailableDate": "</xsl:text>
<xsl:value-of select="fn:concat(fn:substring($vNextDate,1,4),'-',fn:substring($vNextDate,5,2),'-',fn:substring($vNextDate,7,2))"/>
<xsl:text>",</xsl:text>
<xsl:text>"nextAvailableQuantity": </xsl:text>
<xsl:value-of select="next_available/@quantity"/>
</xsl:when>
</xsl:choose>
<xsl:text>,"servicedRegion" : [</xsl:text>
<xsl:for-each select="$vReg//region">
<xsl:text>"</xsl:text>
<xsl:variable name="vRegionCode" select="."/>
<h3>
<xsl:value-of select="$vRegionCode"/>
</h3>
<xsl:if test="fn:contains($vCountryCode,$vRegionCode)">
<xsl:text>"</xsl:text>
<xsl:if test="fn:position() != fn:last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:if>
</xsl:for-each>
<xsl:text>]</xsl:text>
<xsl:text>}</xsl:text>
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text>]}</xsl:text>
</xsl:template>
</xsl:stylesheet>

输入消息:

<?xml version="1.0" encoding="UTF-8"?>
<advice_file as-of-date="2019-06-20T09:45:10.882+01:00" advice-content="incr">
<advice_file_control_number>1561020310882</advice_file_control_number>
<product last-update-date="2019-06-20T08:48:22.583+01:00">
<vendor_SKU>AW23377-GY</vendor_SKU>
<qtyonhand>390</qtyonhand>
<available>YES</available>
<next_available_qty>0</next_available_qty>
<vendor>393</vendor>
<warehouseBreakout>
<warehouse warehouse-id="No merchant (warehouse)ID has been provided.">
<qtyonhand>390</qtyonhand>
<next_available quantity="0"/>
</warehouse>
</warehouseBreakout>
</product>
<product last-update-date="2019-06-20T08:48:22.583+01:00">
<vendor_SKU>AW22226-WH</vendor_SKU>
<qtyonhand>250</qtyonhand>
<available>YES</available>
<next_available_qty>0</next_available_qty>
<vendor>342</vendor>
<warehouseBreakout>
<!--<warehouse warehouse-id="No merchant (warehouse)ID has been provided.">-->
<warehouse warehouse-id="01">
<qtyonhand>250</qtyonhand>
<next_available quantity="0"/>
</warehouse>
</warehouseBreakout>
</product>
<product last-update-date="2019-06-20T09:40:11.797+01:00">
<vendor_SKU>EL-FC22</vendor_SKU>
<qtyonhand>734</qtyonhand>
<available>YES</available>
<min_days_to_fulfill>3</min_days_to_fulfill>
<UPC>4016946199445</UPC>
<next_available_qty>0</next_available_qty>
<vendor>364</vendor>
<warehouseBreakout>
<warehouse warehouse-id="01">
<qtyonhand>734</qtyonhand>
<next_available quantity="0"/>
</warehouse>
</warehouseBreakout>
</product>
<advice_file_count>298</advice_file_count>
</advice_file>

实际结果:

<?xml version="1.0" encoding="UTF-8"?>
"warehouses": [{"warehouseId" : "393-No merchant (warehouse)ID has been provided.","quantity" : 390,"servicedRegion" : []}]}
"warehouses": [{"warehouseId" : "342-01","quantity" : 250,"servicedRegion" : ["<h3>CH</h3>]}]}
"warehouses": [{"warehouseId" : "364-01","quantity" : 734,"servicedRegion" : ["<h3>DE</h3>","<h3>AT</h3>"]}]}

预期输出:

<?xml version="1.0" encoding="UTF-8"?>
"warehouses": [{"warehouseId" : "393-No merchant (warehouse)ID has been provided.","quantity" : 390,"servicedRegion" : []}]}
"warehouses": [{"warehouseId" : "364-01","quantity" : 734,"servicedRegion" : ["<h3>DE</h3>","<h3>AT</h3>"]}]}

参考文件:

<SupplierCrossReference name="Franken">
<TraitID>364</TraitID>
<!--<STEPSupplierID>SU
<xsl:variable name="vReg" select="fn:copy-of($vSupplierCrossReferences/SupplierCrossReference[TraitID=$vVendor]/warehouses/warehouse[@id=$vWH])"/>
888888</STEPSupplierID>--> <!-- NOTE the _C_ added as a tempory fix for Product stream POC --> <STEPSupplierID>SUPP_C_888888</STEPSupplierID> <STEPSuppliers> <Supplier store="DE">**********</Supplier> <Supplier store="AT">**********</Supplier> </STEPSuppliers> <AS400SupplierID>621</AS400SupplierID> <LegacySenderReceiverID>DE-FRANK2</LegacySenderReceiverID> <LegacySenderReceiverID>AT-FRANK2</LegacySenderReceiverID> <ComsysSenderReceiverID>DE-FRANK4</ComsysSenderReceiverID> <ComsysSenderReceiverID>AT-FRANK4</ComsysSenderReceiverID> <warehouses> <warehouse id='01'> <region>DE</region> <region>AT</region> </warehouse> </warehouses> </SupplierCrossReference>

好的,所以在你的XSL中你有:

<xsl:variable name="vSupplierCrossReferences" select="document($vSupplierFullPath)/*:SupplierCrossReferences"/>

但这是错误的,因为您提供的交叉引用文件只有:

<SupplierCrossReference name="Franken">

作为根。因此,将其更改为单数使我可以访问XSL中的交叉引用文件节点。

另一个错误是:

PP_8我把它改成:

<xsl:variable name="vReg" select="fn:copy-of($vSupplierCrossReferences[TraitID=$vVendor]/warehouses/warehouse[@id=$vWH])"/>

通过您提供的数据,这让我们更接近:

<?xml version="1.0" encoding="UTF-8"?>
1561020310882
"warehouses": [{"warehouseId" : "393-No merchant (warehouse)ID has been provided.","quantity" : 390,"servicedRegion" : []}]}
"warehouses": [{"warehouseId" : "342-01","quantity" : 250,"servicedRegion" : []}]}
"warehouses": [{"warehouseId" : "364-01","quantity" : 734,"servicedRegion" : ["<h3>DE</h3>","<h3>AT</h3>"]}]}
298

开头和结尾那些悬而未决的数字很容易纠正 - 只需匹配适当的标签,然后吃掉值(不要吐出任何东西)。

看起来您打算拥有一个具有复数根和单数条目的交叉引用文件,但在此过程中交叉了您的电线。 如果您注意我更改的线条并相应地适当地更改它们,则很容易适应回复数。

至于你突出的担忧,那个额外的"仓库"条目,如果你打算根据某些标准完全抑制其中一些,你为什么要在每个/advice_file/product上都匹配并开始吐出行条目? 我希望看到类似的东西:

<xsl:template match="/advice_file/product[QUALIFYING PREDICATE HERE]" name="xsl:initial-template">

。为了根据适当的标准消除仓库条目。

这不是一个 if问题 - 你的工作表中有一个基本的设计缺陷。

这应该足以让你完成这项工作并到达你要去的地方。 我不会为你做这一切,因为你似乎知道的足够多,可以从这里拿走它。

希望有帮助。

最新更新