首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >XSLT 1.0拆分变量字符串以填充特定标记

XSLT 1.0拆分变量字符串以填充特定标记
EN

Stack Overflow用户
提问于 2019-06-10 22:28:59
回答 1查看 48关注 0票数 0

我使用XSLT1.0将数据从一种xml格式转换为另一种格式。在输入xml中,address作为由空格分隔的字符串出现在单个字段中。据我所知,考虑到括号[]中的标识符是可选的,它可以采用以下格式。

代码语言:javascript
复制
<Field Name="address"...>number [cardinal-dir] name st-type [unit#]</Field>

代码语言:javascript
复制
<Field Name="address"...>number [cardinal-dir] name st-type APT APT#</Field>

因此,数据可能如下所示:"123第三大道“或"123东北第三大道”或"123东北第三大道APT 321“...你就明白了。

并且我需要它来适当地填充以下输出格式:

代码语言:javascript
复制
<mstns:Address>
    <mstns:HouseNumber>123</mstns:HouseNumber>
    <mstns:StreetName>NE</mstns:StreetName>
    <mstns:StreetType>AVE</mstns:StreetType>
    <mstns:Apt>APT</mstns:Apt>
</mstns:Address>

我在xlst 1.0中看到过一些关于字符串标记化的类似帖子,但是结合变量input,我有点迷惑。

EN

回答 1

Stack Overflow用户

发布于 2019-06-13 02:30:52

正如我在评论中所说,这是一项可怕的工作,结果的质量将取决于您的数据的一致性。

假设:

街道名称(

  1. )第一个单词(并且仅第一个单词)是街道号码;街道名称第二个单词可以是街道方向标识符,从街道方向的已知列表中
    1. 后面跟随街道类型标识符,从街道类型标识符的已知列表

您可以使用以下样式表作为起点:

XSLT1.0 (+EXSLT节点集)

代码语言:javascript
复制
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Field[@Name='address']">
    <!-- tokenize to words -->
    <xsl:variable name="tokens">
        <xsl:call-template name="tokenize">
            <xsl:with-param name="text" select="."/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="words" select="exsl:node-set($tokens)/token" />

    <!-- street direction exists? -->
    <xsl:variable name="street-direction-exists" select="$words[2]='N' or $words[2]='E' or $words[2]='S' or $words[2]='W' or $words[2]='NE' or $words[2]='NW' or $words[2]='SE' or $words[2]='SW'" />

    <!-- find position of street type -->
    <xsl:variable name="street-type-index">
        <xsl:call-template name="get-street-type-index">
            <xsl:with-param name="words" select="$words"/>
        </xsl:call-template>
    </xsl:variable>

    <!-- output -->
    <Address>
        <HouseNumber>
            <xsl:value-of select="$words[1]"/>
        </HouseNumber>
        <xsl:if test="$street-direction-exists">
            <StreetDirection>
                <xsl:value-of select="$words[2]"/>
            </StreetDirection>
        </xsl:if>
        <StreetName>            
            <xsl:for-each select="$words[1 + $street-direction-exists &lt; position() and position() &lt; $street-type-index]">
                <xsl:value-of select="."/>
                <xsl:if test="position() != last()">
                    <xsl:text> </xsl:text>
                </xsl:if>
            </xsl:for-each>
        </StreetName>
        <StreetType>
            <xsl:value-of select="$words[number($street-type-index)]"/>                     
        </StreetType>
        <xsl:if test="count($words) > $street-type-index">
            <Unit>
                <xsl:for-each select="$words[position() > $street-type-index]">
                    <xsl:value-of select="."/>
                    <xsl:if test="position() != last()">
                        <xsl:text> </xsl:text>
                    </xsl:if>
                </xsl:for-each>
            </Unit>
        </xsl:if>
    </Address>
</xsl:template>

<xsl:template name="tokenize">
    <xsl:param name="text"/>
    <xsl:param name="delimiter" select="' '"/>
    <token>
        <xsl:value-of select="substring-before(concat($text, $delimiter), $delimiter)" />
    </token>
    <xsl:if test="contains($text, $delimiter)">
        <!-- recursive call -->
        <xsl:call-template name="tokenize">
            <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<xsl:template name="get-street-type-index">
    <xsl:param name="words"/>
    <xsl:variable name="street-types">
        <street-type>AVE</street-type>
        <street-type>STR</street-type>
        <!-- add more types here (or use an external XML document for them) -->
    </xsl:variable>
    <xsl:choose>
        <xsl:when test="$words[last()] = exsl:node-set($street-types)/street-type">
            <xsl:value-of select="count($words)"/>
        </xsl:when>
        <xsl:when test="$words">
            <!-- recursive call -->
            <xsl:call-template name="get-street-type-index">
                <xsl:with-param name="words" select="$words[position() != last()]"/>
            </xsl:call-template>
        </xsl:when>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

应用于以下测试输入:

XML

代码语言:javascript
复制
<Fields>
    <Field Name="address">123 Old Oak Tree AVE</Field>
    <Field Name="address">45B NE Broadway STR</Field>
    <Field Name="address">6789 Maple Syrup AVE Room 800</Field>
    <Field Name="address">1024 W Three Elm Trees AVE APT 321</Field>
    <Field Name="address">1024 False AVE Maria STR Unit 8071</Field>
</Fields>

结果将是:

结果

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-16"?>
<Fields>
  <Address>
    <HouseNumber>123</HouseNumber>
    <StreetName>Old Oak Tree</StreetName>
    <StreetType>AVE</StreetType>
  </Address>
  <Address>
    <HouseNumber>45B</HouseNumber>
    <StreetDirection>NE</StreetDirection>
    <StreetName>Broadway</StreetName>
    <StreetType>STR</StreetType>
  </Address>
  <Address>
    <HouseNumber>6789</HouseNumber>
    <StreetName>Maple Syrup</StreetName>
    <StreetType>AVE</StreetType>
    <Unit>Room 800</Unit>
  </Address>
  <Address>
    <HouseNumber>1024</HouseNumber>
    <StreetDirection>W</StreetDirection>
    <StreetName>Three Elm Trees</StreetName>
    <StreetType>AVE</StreetType>
    <Unit>APT 321</Unit>
  </Address>
  <Address>
    <HouseNumber>1024</HouseNumber>
    <StreetName>False AVE Maria</StreetName>
    <StreetType>STR</StreetType>
    <Unit>Unit 8071</Unit>
  </Address>
</Fields>

EXSLT:你可能需要使用微软自己的node-set()扩展函数,而不是EXSLT.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56528370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档