【问题标题】:XSLT using regex patternXSLT 使用正则表达式模式
【发布时间】:2017-04-18 04:04:19
【问题描述】:

我需要根据@schemeNames 的优先级获取值。如果存在@schemeName='TaxNumber',则获取ID 的值,否则如果@schemeName='PassportNumber',否则如果@schemeName 没有值。获取到值后,如果是 Alpha,则需要检查或忽略第 1 2 个字符。另外,我需要考虑@schemeName 中单词之间的空格。例如,如果我的 @schemeName 的值为“税号”或“税号”,则它是有效的。但是如果值是这样的,'t axNum Ber',它不应该验证这个值。

这是我的 XSLT:

<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:template match="/">
    <Result>
        <xsl:for-each select="/Record/Data/ID">
            <xsl:choose>
                <xsl:when test="matches(lower-case(.[@schemeName]),'^tax\s+number')">
                    <xsl:if test="matches(substring(.,1,2),'^[a-zA-Z]+$')">
                        <xsl:value-of select="substring(.,3)"/>
                    </xsl:if>
                </xsl:when>
                <xsl:when test="matches(lower-case(.[@schemeName]),'^passport\s+number')">
                    <xsl:if test="matches(substring(.,1,2),'^[a-zA-Z]+$')">
                        <xsl:value-of select="substring(.,3)"/>
                    </xsl:if>
                </xsl:when>
                <xsl:when test=".[@schemeName='']">
                    <xsl:if test="matches(substring(.,1,2),'^[a-zA-Z]+$')">
                        <xsl:value-of select="substring(.,3)"/>
                    </xsl:if>
                </xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </Result>
</xsl:template>
</xsl:stylesheet>

输入:

<Record>
    <Data>
    <ID schemeName="TaxNumber">PT123457</ID>
    <ID schemeName="PassportNumber">PT098732</ID>
    <ID schemeName="LicenseNumber">PT445423</ID>
    <ID schemeName="">PT7566435</ID>
</Data>
</Record>

生成的输出:

<Result>7566435</Result>

生成的输出来自为空的@schemeName。它应该来自 TaxNumber,因为它存在。检查@schemeNames 时,我的情况有问题。

我正在使用 XSLT v2.0。谢谢!

【问题讨论】:

    标签: regex xslt xslt-2.0


    【解决方案1】:

    如何在变量中设置优先级?比如:

        <xsl:variable name="prio1" select="ID[matches(lower-case(@schemeName),'^tax\s?number')]"/>
        <xsl:variable name="prio1_value">
            <xsl:choose>
                <xsl:when test="matches($prio1, '^[A-z]{2}.*$')">
                    <xsl:value-of select="substring($prio1,3)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$prio1"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
    
        <xsl:variable name="prio2" select="ID[matches(lower-case(@schemeName),'^passport\s?number')]"/>
        <xsl:variable name="prio2_value">
            <xsl:choose>
                <xsl:when test="matches($prio2, '^[A-z]{2}.*$')">
                    <xsl:value-of select="substring($prio2,3)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$prio2"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
    
        <xsl:variable name="prio3" select="ID[@schemeName='']"/>
        <xsl:variable name="prio3_value">
            <xsl:choose>
                <xsl:when test="matches($prio3, '^[A-z]{2}.*$')">
                    <xsl:value-of select="substring($prio3,3)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$prio3"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
    

    注意:我已将\s+ 更改为\s? 以使空格可选。

    此外,您可以在 xslt 2.0 中使用 if-then-else 构造。最终代码如下:

    <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:template match="/">
            <xsl:apply-templates select="Record/Data"/>
        </xsl:template>
    
        <xsl:template match="Data">
        <xsl:variable name="prio1" select="ID[matches(lower-case(@schemeName),'^tax\s?number')]"/>
        <xsl:variable name="prio1_value">
            <xsl:choose>
                <xsl:when test="matches($prio1, '^[A-z]{2}.*$')">
                    <xsl:value-of select="substring($prio1,3)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$prio1"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
    
        <xsl:variable name="prio2" select="ID[matches(lower-case(@schemeName),'^passport\s?number')]"/>
        <xsl:variable name="prio2_value">
            <xsl:choose>
                <xsl:when test="matches($prio2, '^[A-z]{2}.*$')">
                    <xsl:value-of select="substring($prio2,3)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$prio2"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
    
        <xsl:variable name="prio3" select="ID[@schemeName='']"/>
        <xsl:variable name="prio3_value">
            <xsl:choose>
                <xsl:when test="matches($prio3, '^[A-z]{2}.*$')">
                    <xsl:value-of select="substring($prio3,3)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$prio3"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
    
        <Result>
            <xsl:value-of select="if ($prio1) then ($prio1_value) else 
            if ($prio2) then ($prio2_value) else
            if ($prio3) then ($prio3_value) else 0"/>
        </Result>
    
        </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 感谢您的反馈。它确实有效,但唯一的问题是我只需要检查前 2 个字符是否为 alpha。其他位置有没有字母没关系。
    • 如果它是一个有效的schemeName,并且如果前2个字母不是alpha,那么你没有输出?
    • 如果它是一个有效的schemeName,并且如果前2个字母不是alpha,则按原样获取值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    相关资源
    最近更新 更多