xml - 如何使用 XSLT 2.0 替换地址字符串中的多个地址缩写

标签 xml xslt xslt-2.0

给出:XSLT 2.0;撒克逊EE 9.6.0.4

源 XML:

<clients>
    <client id="1">
        <address>12345 Elm Dr</address>
    </client>
    <client id="2">
        <address>12345 Elm Cr</address>
    </client>
</clients>

我需要对地址进行一些比较,以查找匹配项,其中一个地址可能使用缩写,而我要比较的地址可能不使用缩写。以下是我的意思的几个例子:

Ave = Avenue
Blvd = Boulevard
Cir = Circle
Ct = Court
Dr = Drive
Hwy = Highway

搜索到的地址作为参数传递到样式表,因此假设该地址已传递到以下示例样式表:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:param name="searchAddr">12345 Elm Drive</xsl:param>
    <xsl:variable name="punctuation">
        <xsl:text> .!@#$%^*()_+{}[]|`\:;?,*-=/</xsl:text>
    </xsl:variable>
    <xsl:template match="/">
        <xsl:for-each select="clients/client[address[upper-case(translate(.,$punctuation,'')) = upper-case(translate($searchAddr,$punctuation,''))]]">
            <xsl:copy-of select="."/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

注意: --我已经使用 translate() 删除所有标点符号,并使用 upper-case() 来控制比较中的大小写。

--我不需要永久替换输出中的字符串,我只需要替换它们以进行比较。

--我们意识到这不是 100% 可靠的地址匹配方法,但在这种情况下我们不需要它......只是想获得唾手可得的成果。

我认为有比 20 个嵌套替换函数或调用模板循环每个缩写更好的方法。有想法吗?

最佳答案

我不知道是否有比嵌套/链接 20 个替换操作更优雅的方法。我认为不存在,只有不同的方式来表达该操作。

那么继续生活怎么样:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*" />

    <xsl:param name="searchAddr">12345 Elm Drive</xsl:param>

    <xsl:key name="sanitized-adresses" match="client" use="
        replace(
        replace(
        replace(
        replace(
        replace(
        replace(
        replace(
            upper-case(normalize-space(address))
        ,'\p{P}', '')
        ,'(^|\W)AVE($|\W)', '$1AVENUE$2')
        ,'(^|\W)DR($|\W)', '$1DRIVE$2')
        ,'(^|\W)BLVD($|\W)', '$1BOULEVARD$2')
        ,'(^|\W)CI?R($|\W)', '$1CIRCLE$2')
        ,'(^|\W)CT($|\W)', '$1COURT$2')
        ,'(^|\W)HWY($|\W)', '$1HIGHWAY$2')
    " />

    <xsl:template match="/">
        <xsl:copy-of select="key('sanitized-adresses', upper-case($searchAddr))" />
    </xsl:template>
</xsl:stylesheet>

注释:

  • \p{P}是匹配所有标点符号的 Unicode 字符类。
  • XSLT 2.0 正则表达式没有字边界,因此 (^|\W)($|\W)\b 的替代品.
  • 它也没有后视或前视,因此我们需要 $1$2在替换字符串中。
  • 我包括了normalize-space()避免空格问题
  • <xsl:key>并不是绝对必要的,我添加它是为了使主模板看起来更美观。

如果需要,请创建 <xsl:function>这样就可以进行地址清理,这样你就可以重复使用它来清理参数,使整体使用更加方便。

关于xml - 如何使用 XSLT 2.0 替换地址字符串中的多个地址缩写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35751270/

相关文章:

xml - PostgreSQL 8.3 数据类型 : xml vs varchar

xml - XSL 递归排序

java - XSL - 匹配节点的文本并附加另一个节点作为同级节点

xml - 多个xsl选择条件

c# - 从 xslt 中,您可以输出整个 XML 吗?

xml - 将多个元素值连接到 xslt 2.0 中的新字符串的最佳方法是什么

xslt - 无法获得正确的 XSLT 输出

java - 自定义适配器不在 ListView 中显示文本

java - solr 多核发布数据

python - 使用 python 在 XML 文件中编码表情符号