xslt由定界符分割

时间:2019-10-04 15:19:28

标签: xml xslt delimiter tokenize

我不能使用标记化(xslt 2.0)

我有问题。我需要根据定界符“ \ n”分割一个值“ Test street \ nStreet 2 \ nStreet3”来生成

        <address1>Test street</address3>
        <address2>Street 2</address3>
        <address3>Street3</address3>

到目前为止,我已经拥有了:

<xsl:call-template name="tokenize">
    <xsl:with-param name="text" select="ns0:sObject/ens:BillingStreet"/>
</xsl:call-template>

<xsl:template name="tokenize">
    <xsl:param name="text"/>
    <xsl:param name="separator" select="'\n'"/>
    <xsl:choose>
        <xsl:when test="not(contains($text, $separator))">
            <Address>
                <xsl:value-of select="normalize-space($text)"/>
            </Address>
        </xsl:when>
        <xsl:otherwise>
            <Address>
                <xsl:value-of select="normalize-space(substring-before($text, $separator))"/>
            </Address>
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $separator)"/>
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

它给了我这个

        <Aaddress>Test street</Address>
        <Aaddress>Street 2</Address>
        <Aaddress>Street3</Address>

我尝试使用position(),但无法正常工作:

<xsl:template name="tokenize">
    <xsl:param name="text"/>
    <xsl:param name="separator" select="'\n'"/>
    <xsl:choose>
        <xsl:when test="not(contains($text, $separator))">
            <xsl:element name="Address{position()}">
                <xsl:value-of select="normalize-space($text)"/>
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="Address{position()}">
                <xsl:value-of select="normalize-space(substring-before($text, $separator))"/>
            </xsl:element>
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $separator)"/>
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

上面给了我:

        <Address1>Test street</Address1>
        <Address1>Street 2</Address1>
        <Address1>Street3</Address1>

再次,我正在寻找的是:

        <Address1>Test street</Address1>
        <Address2>Street 2</Address2>
        <Address3>Street3</Address3>

有什么主意吗?

谢谢

2 个答案:

答案 0 :(得分:1)

position()在这里并不重要,因为它返回当前选定节点的位置。

您将不得不通过另一个参数来跟踪递归模板正在进行的迭代:

<xsl:template name="tokenize">
    <xsl:param name="text"/>
    <xsl:param name="separator" select="'\n'"/>
    <xsl:param name="pos" select="1" ></xsl:param>
    <xsl:choose>
        <xsl:when test="not(contains($text, $separator))">
            <xsl:element name="Address{$pos}">
                <xsl:value-of select="normalize-space($text)"/>
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="Address{$pos}">
                <xsl:value-of select="normalize-space(substring-before($text, $separator))"/>
            </xsl:element>
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $separator)"/>
                <xsl:with-param name="pos" select="$pos + 1" />
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template> 

注意,您可以稍微简化模板,以免由于创建Address元素而导致代码重复。像这样:

<xsl:template name="tokenize">
    <xsl:param name="text"/>
    <xsl:param name="separator" select="'\n'"/>
    <xsl:param name="pos" select="1" ></xsl:param>

    <xsl:element name="Address{$pos}">
        <xsl:value-of select="normalize-space(substring-before(concat($text, $separator), $separator))"/>
    </xsl:element>
    <xsl:if test="contains($text, $separator)" >
        <xsl:call-template name="tokenize">
            <xsl:with-param name="text" select="substring-after($text, $separator)"/>
            <xsl:with-param name="pos" select="$pos + 1" />
        </xsl:call-template>
    </xsl:if>
</xsl:template>  

答案 1 :(得分:0)

'\n'不是带有换行符的字符串...使用字符引用'&#xA;'

除此之外,请注意position()函数针对当前上下文列表起作用。调用命名模板后,这种情况不会改变。因此,您的样式表片段取决于您尚未显示给我们的其他部分。