使用相同的XSLT匹配来自不同XML的不同输入值

时间:2017-05-12 14:14:09

标签: xml xslt

我正在开发一个XSLT,我正在检查下面的传入XML:

输入1:

<URLS src="test">
<url name="1a">!#$%&'-.01=?@A[ ]^_`ab</url>
<url name="2q">4!%'-.321=?@&D[$]^_ `zs#</url></URLS>

输入2:

<URLS src="test">
<url name="1a">abXZ12</url>
<url name="2q">abXZ12uednd</url></URLS>

输入3:

<URLS src="test">
<url name="1a">qwqwqs</url>
<url name="2q">dhjekoop</url></URLS>

我在这里做的是,

  1. 检查1a的字符串长度,使其介于2到30个字符之间,且不应与2q具有相同的值。

  2. 如果步骤1没问题,那么检查2q的值,使字符串长度在4到30之间,并与正则表达式匹配。

  3. 如果处理完第2步,则应打印1a Ok

  4. 1a或2q的值可能包含以下字符: !#$%&amp;&#39; - .0123456789 =?@ABCDEFGHIJKLMNOPQRSTUVWXYZ [SPACE] ^ _` abcdefghijklmnopqrstuvwxyz {|}

    我使用下面的XSLT来实现这个目标:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   xmlns:regexp="http://exslt.org/regular-expressions" extension-element-prefixes="regexp" exclude-result-prefixes="regexp">
    <xsl:output method="xml" encoding="UTF-8" indent="no" />
    <xsl:template match="/">
        <xsl:variable name="1a" select="normalize-space(/URLS/url[@name='1a']/text())" />
        <xsl:variable name="2q" select="normalize-space(/URLS/url[@name='2q']/text())" />
        <xsl:choose>
            <xsl:when test="string-length($1a) &gt; 2 and string-length($1a) &lt;= 30 and not(regexp:test($2q, '.*^[a-z0-9A-Z\s?@`!#$%^&amp;=\[\]{_}'&apos;|.-}]+$.*', 'gi') )">
                <xsl:choose>
                    <xsl:when test="string-length($2q) &gt; 4 and string-length($2q) &lt; 30 and (regexp:test($2q, '.*^[a-z0-9A-Z\s?@`!#$%^&amp;=\[\]{_}'&apos;|.-}]+$.*', 'gi') )">
                        <xsl:element name="status">2q Ok</xsl:element>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:element name="status">terminate for 2q disallowed length</xsl:element>
                    </xsl:otherwise>
                </xsl:choose>
                <xsl:element name="status">1a Ok</xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:element name="status">terminate for 1a disallowed length</xsl:element>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    

    这个XSLT几乎可以工作,唯一的问题是我无法正确匹配正则表达式。任何帮助都会非常有用。

1 个答案:

答案 0 :(得分:0)

您的正则表达式似乎有问题。您正在使用的相关部分是(非正则表达式谓词已删除):

regexp:test($2q, '.*^[a-z0-9A-Z\s?@`!#$%^&=\[\]{_}''|.-}]+$.*', 'gi')

首先,请注意在构建样式表树时处理样式表属性值中的实体引用,因此该属性传达的函数调用表达式为:

.*

有几点需要注意:

  • 正则表达式字符串不是格式良好的XPath字符串文字,因为它是撇号分隔但内部出现两个文字撇号。

  • 前导和尾随xsl-choose没用,因为在它们之间你将模式的其余部分锚定到输入的开头和结尾

  • &#39;&#39; flag与此功能无关,而且&#39; i&#39;我没有为你做任何事,因为你在正则表达式中直接考虑了大写和小写字母。

此外,仅当$2q 的值与正则表达式匹配时,才会采用外部<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:regexp="http://exslt.org/regular-expressions" extension-element-prefixes="regexp" exclude-result-prefixes="regexp"> <xsl:output method="xml" encoding="UTF-8" indent="no" /> <xsl:template match="/"> <xsl:variable name="1a" select="normalize-space(/URLS/url[@name='1a'])" /> <xsl:variable name="2q" select="normalize-space(/URLS/url[@name='2q'])" /> <xsl:choose> <xsl:when test="string-length($1a) &gt; 2 and string-length($1a) &lt;= 30"> <xsl:choose> <xsl:when test='string-length($2q) &gt; 4 and string-length($2q) &lt; 30 and regexp:test($2q, "^[a-z0-9A-Z\s?@`!#$%^&amp;=\[\]{_}&apos;|.-]+$")'> <xsl:element name="status">2q Ok</xsl:element> </xsl:when> <xsl:otherwise> <xsl:element name="status">terminate for 2q disallowed length</xsl:element> </xsl:otherwise> </xsl:choose> <xsl:element name="status">1a Ok</xsl:element> </xsl:when> <xsl:otherwise> <xsl:element name="status">terminate for 1a disallowed length</xsl:element> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> 的第一个替代方法,因此永远不会出现这种情况。在该替代方案中的测试将发现相同的变量然后 匹配相同的正则表达式。您似乎根本不想进行第一次测试。

其中,引用问题可能是最棘手的,但在这种特殊情况下,您应该能够通过反转引用样式来解决它。此变体保留样式表的结构,但解决了所有这些问题:

/imports