如何使用XPath在一系列字符串中搜索特定字符串?

时间:2019-09-03 07:56:20

标签: xml xslt xpath

我正在尝试寻找一些方法来搜索产品名称中的vendor-sku。我在供应商Feed的<vendor-sku>HT900C</vendor-sku>中匹配了零售商Feed中的<vendor-product-name>Ventilateur TurboForce&#7481;&#7472; HT900C Honeywell</vendor-product-name>的值。

供应商的供稿:

<?xml version="1.0" encoding="UTF-8"?>
<products module-id="kazfanscafr">
<product type="product" wcpc="1562772927361"><gtin>00092926109004</gtin><vendor-product-name>Ventilateur TurboForce&#7481;&#7472; **HT900C** Honeywell</vendor-product-name><provided-by>Kaz</provided-by>
<product type="product" wcpc="1562774715788"><gtin>00092926310905</gtin><vendor-product-name>Ventilateur Turbo&#7481;&#7472; On the GO! HTF090BC Honeywell</vendor-product-name><vendor-clean-product-name>Ventilateur Turbo&#7481;&#7472; On the GO **HTF090BC** Honeywell</vendor-clean-product-name><provided-by>Kaz</provided-by>
</products>

零售商的供稿:

<product><vendor>KAZ CANADA INC</vendor><vendor-sku>**HT900C**</vendor-sku><channel-product-name>Fan, High Performance, 8", Black</channel-product-name><channel-product-id>KAZHT900C</channel-product-id><on-sale>true</on-sale><product-url>https://www.eway.ca/Eway/Product/KAZHT900C.aspx</product-url></product>
<product><vendor>KAZ CANADA INC</vendor><vendor-sku>**HTF090BC**</vendor-sku><channel-product-name>Honeywell Turbo on the Go, portable fan</channel-product-name><channel-product-id>KAZHTF090BC</channel-product-id><on-sale>true</on-sale><product-url>https://www.eway.ca/Eway/Product/KAZHTF090BC.aspx</product-url></product>
<product><vendor>KAZ CANADA INC</vendor><vendor-sku>HTF1220C</vendor-sku><channel-product-name>HONEYWELL 12" Portable Table Fan</channel-product-name><channel-product-id>KAZHTF1220C</channel-product-id><on-sale>true</on-sale><product-url>https://www.eway.ca/Eway/Product/KAZHTF1220C.aspx</product-url></product>
<product><vendor>KAZ CANADA INC</vendor><vendor-sku>HTF210BC</vendor-sku><channel-product-name>Quietset table fan</channel-product-name><channel-product-id>KAZHTF210BC</channel-product-id><on-sale>true</on-sale><product-url>https://www.eway.ca/Eway/Product/KAZHTF210BC.aspx</product-url></product>

因此,我的工作基本上是在这两个摘要之间找到匹配项,我需要将供应商的SKU / GTIN与发布在零售商站点/摘要上的产品的SKU / GTIN相匹配。我正在向产品注入丰富的内容,为此,我需要在两个提要之间将这些ID匹配为渠道或桥梁。但是由于这种情况,由于产品名称上插入了SKU,所以我寻求帮助。

通常,我可以使用默认操作来搜索其ID:

<xsl:call-template name="search-feeds-by-sku"> <xsl:with-param name="vendor-data-feed-field-to-compare" select="'gtin'" wcmt:editorDisplay="hidden"/> <xsl:with-param name="product-data-feed-field-to-compare" select="'gtin'" wcmt:editorDisplay="hidden"/> </xsl:call-template>

但是在这种情况下。我需要做一个子串或一个正则表达式来操纵结果

我已经尝试了不同的子字符串函数。由于产品名称格式不一致,我无法使其在substring-after和substring-before上起作用。

<method confidence="0.9" display-name="map-feed-by-name" xsi:type="map-by-virtual-feed"><product-data-matcher>/products/product[contains(vendor-sku, '{concat('vendor-product-name', " ")}')]</product-data-matcher>
            </method>

因此,我希望在产品名称中找到vendor-sku(HT900C),因为我是用“”(空格)连接的。

输出应为:

Ventilateur

TurboForce&#7481;&#7472;

HT900C

Honeywell

到那时我应该得到一个匹配的HT900C,但是它什么也没返回。我想知道我是否错过了什么,还是完全不建议使用这种整体方法。我正在使用XPath 1.0,处理器是XSLT 2.0。感谢您的提前帮助!

这是我当前的解决方案

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:import href="eway-fr-ca-fr/map-common.xml" xml:base="{$common-folder-uri}/"/>
   <xsl:template match="/"<map-operation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" channel-id="eway-fr-ca-fr" module-id="kazfanscafr">
         <skip-if-no-new-channel-product-found ttl-hours="720"/>
         <allow-multiple-mappings/>
         <methods>
            <xsl:call-template name="search-feeds-by-sku"/>
            <xsl:call-template name="search-feeds-by-sku">
               <xsl:with-param name="vendor-data-feed-field-to-compare" select="'gtin'" wcmt:editorDisplay="hidden"/>
               <xsl:with-param name="product-data-feed-field-to-compare" select="'gtin'" wcmt:editorDisplay="hidden"/>
            </xsl:call-template>
            <method confidence="0.9" display-name="map-feed-by-name" xsi:type="map-by-virtual-feed">
               <product-data-matcher>/products/product[contains(vendor-sku, '{concat(vendor-product-name, " ")}')]</product-data-matcher>
            </method>
         </methods>
      </map-operation>
    </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:0)

您应该共享XML,直到该供应商产品名称为止,以获取确切的解决方案。

如果XML如下:

<vendor-sku>HT900C</vendor-sku>
 <vendor-product-name>Ventilateur TurboForce&#7481;&#7472; HT900C Honeywell</vendor-product-name>

如果<vendor-product-name>不是兄弟姐妹而不是孩子,那么您共享的数据将与下面创建的xpath共享:

//vendor-sku[contains(.,'HT900C')]//following-sibling::vendor-product-name

如果<vendor-product-name>是孩子

 //vendor-sku[contains(.,'HT900C')]//vendor-product-name

如果<vendor-product-name>是父母

//vendor-sku[contains(.,'HT900C')]//../self::vendor-product-name

答案 1 :(得分:0)

这部分问题不太清楚:

  

我正在尝试寻找一些方法来搜索产品名称中的vendor-sku。

如果您有多个vendor-product-name节点,则可以选择一个包含已知值的节点,如以下示例所示:

XML

<input>
    <vendor-product-name>Gadget Cornballer100 CBL0100 Acme</vendor-product-name>
    <vendor-product-name>Widget Sabor5000 SBRX5 Roxxon</vendor-product-name>
    <vendor-product-name>Ventilateur TurboForce&#7481;&#7472; HT900C Honeywell</vendor-product-name>
    <vendor-product-name>Thingy Opti-Grab OPG-45A Zaibatsu</vendor-product-name>
</input>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:param name="sku">HT900C</xsl:param>

<xsl:template match="/input">
    <xsl:variable name="my-product" select="vendor-product-name[contains(concat(' ', ., ' '), concat(' ', $sku, ' '))]" />
    <xsl:value-of select="translate($my-product, ' ', '&#10;')"/>
</xsl:template>

</xsl:stylesheet>

结果

Ventilateur
TurboForceᴹᴰ
HT900C
Honeywell

如果您使用的是libxslt处理器,则可以通过专门定位vendor-product-name中的第三个令牌来减少误报的机会:

XSLT 1.0 + EXSLT str:tokenize()函数

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">
<xsl:output method="text"/>

<xsl:param name="sku">HT900C</xsl:param>
<xsl:key name="product-by-sku" match="vendor-product-name" use="str:tokenize(., ' ')[3]" />

<xsl:template match="/input">
    <xsl:variable name="my-product" select="key('product-by-sku', $sku)" />
    <xsl:value-of select="translate($my-product, ' ', '&#10;')"/>
</xsl:template>

</xsl:stylesheet>