【问题标题】:How to search a specific string inside a series of string using XPath?如何使用 XPath 在一系列字符串中搜索特定字符串?
【发布时间】:2019-09-03 07:56:20
【问题描述】:

我正在尝试找到一些方法来搜索产品名称中的供应商 Sku。我正在匹配供应商提要上 <vendor-product-name>Ventilateur TurboForceᴹᴰ HT900C Honeywell</vendor-product-name> 中零售商提要中 <vendor-sku>HT900C</vendor-sku> 的值。

供应商供稿:

<?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>

所以我希望在产品名称中找到供应商 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>

【问题讨论】:

  • 请说出您使用的 XPath 版本。很多人还在使用 XPath 1.0,但是在以后的版本中这种问题就容易多了。
  • 如果输入格式不一致,则无法可靠解析。在给定的示例中,您似乎可以使用空格作为分隔符简单地 tokenize 输入。 XSLT 1.0 和 XSLT 2.0 中的标记化方式不同 - 请告诉我们您使用的是哪个处理器。
  • 嗨。我使用的是 XPath 1.0,处理器是 XSLT 2.0
  • 这毫无意义。如果处理器支持 XSLT 2.0,那么它也支持 XPath 2.0。请按照此处的说明识别您的处理器:stackoverflow.com/questions/25244370/…
  • 抱歉!我使用的是遗留系统,所以我只需要询问研发团队,这就是他们为我提供的。但经检查:版本:1.0 供应商:libxslt

标签: xml xslt xpath


【解决方案1】:

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

如果 XML 如下:

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

如果&lt;vendor-product-name&gt; 是兄弟而不是孩子,则您拥有的数据共享以下我创建的 xpath:

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

如果&lt;vendor-product-name&gt; 是孩子

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

如果&lt;vendor-product-name&gt; 是父母

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

【讨论】:

  • Shubham,感谢您的解决方案。对我来说,这似乎是一种更具体的方法。我要查找的是 中的
  • anser 更新 .. xpath : //vendor-sku[contains(.,'HT900C')]//../self::vendor-product-name
  • Shubham,我在我的操作中应用了你的算法:/products/product['{vendor-product-name}'[contains(., vendor-sku)]] 我不会想要设置一个特定的字符串来搜索和映射,我正在使用字段“”来创建匹配项
【解决方案2】:

你的这部分问题不是很清楚:

我正在尝试找到一些方法来搜索产品名称中的供应商 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>

【讨论】:

  • 我们快到了!所以,我有两个提要:一个是我们所谓的供应商提要(三星、宝洁、美泰等),另一个是零售商的提要(沃尔玛、CVS、Target、Newegg)所以我的工作基本上是找到这两个提要之间的匹配项,我需要将供应商的 SKU/GTIN 与零售商网站/提要上发布的产品相匹配。我正在向产品中注入丰富的内容,因此,我需要将这两个提要之间的这些 ID 匹配为渠道或桥梁。但是因为在这个案例中,我请求帮助,因为 SKU 被插入到产品名称中。
  • 请不要在 cmets 中发布代码。编辑您的问题并在此处添加所有相关信息 - 请参阅:minimal reproducible example。 - 我不知道你所说的“饲料”是什么意思。 XSLT 处理单个 XML 文档。您可以通过在运行时传递参数来添加更多信息和/或您可以使用 document() 函数将其指向另一个 XML 文档。
  • 嗨迈克尔,感谢您的耐心等待!我对我的查询进行了一些更新。我所说的提要,它们是 .xml 文件,其中包含供应商和零售商的产品等信息
  • 恐怕我无法遵循所有这些。
  • 没关系,迈克尔。非常感谢您的帮助! :)
猜你喜欢
  • 2020-09-29
  • 1970-01-01
  • 2011-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-07
  • 1970-01-01
相关资源
最近更新 更多