我已经有了答案,但我想了解它的工作原理,我还不确定。
我有以下变量填充匹配:
<xsl:variable name="invalid_characters" as="xs:string*">
<xsl:analyze-string select="$urlToValidate" regex="{$regex}">
<xsl:matching-substring>
<xsl:value-of select="."/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:variable>
然后我希望模板对该变量做一些事情,以防它不为空或空,所以我问这样:
<xsl:if test="not($invalid_characters='')">
<error>The error</error>
</xsl:if>
问题是if总是如此......即使变量是空的,我也必须这样做才能工作
<xsl:if test="$invalid_characters!=''">
<error>The error</error>
</xsl:if>
让我感到困扰的是,如果我做这样的事情:
<xsl:if test="$invalid_characters=''">
<error>The error</error>
</xsl:if>
if语句会做它应该做的事情,所以,任何人都知道为什么我先做的事情不能正常工作?
提前致谢:)
---编辑:有人说这个问题很难理解,所以我举一个例子。
在这里,您可以看到带有两个if语句和输入的xslt的完整示例。
的xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates select="//@*"/>
</xsl:template>
<xsl:template match="@href[not(../scope) or ../scope='local']|@conref|@conrefend">
<xsl:variable name="urlToValidate" select="if(substring-before(.,'#')='')
then .
else substring-before(.,'#')"/>
<xsl:variable name="regex">[\$'%\*\./=\\<>_\(\)\[\]:;,\^~\?|@!\+&\}\{]</xsl:variable>
<xsl:variable name="invalid_characters" as="xs:string*">
<xsl:analyze-string select="$urlToValidate" regex="{$regex}">
<xsl:matching-substring>
<xsl:value-of select="."/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:if test="not($invalid_characters='')">
<error1>
<xsl:value-of select="."/>
</error1>
</xsl:if>
<xsl:if test="$invalid_characters!=''">
<error2>
<xsl:value-of select="."/>
</error2>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这是输入:
<links>
<image conrefend="GUID-6A680D85-10FA-4BCC-B57D-B5138ABE6A59" />
<image conrefend="GUID-1F14088D-4376-46FF-AE6F-937C2AAF5A43" />
<image conrefend="GUID-BB4F234D-3584-4B92-B9CB-D91FBD913B8D#GUID-BB4F234D-584-4B92-B9CB-D91FBD913B8D/MSCPDR1" />
<image conrefend="GUID-6E03D2D4-3FA9-4437-8689-06B873FB56CB" />
<image conrefend="GUID-C97E0253-73C1-4A27-B43E-7A913400BBB8" />
<image conrefend="COPY-GUI'D-86241639-37CD-4CF7-A7AA-F09F4A763944"/>
<image conrefend="COPY-GUID-86241639-37CD-4CF7-A7AA-F09F4A763944"/>
<image conref="COPY-GUID/*+-862416}39-37CD-4CF7-A7AA-F09F4A763944" />
<image conrefend="COPY-GUID-8624163{9-37CD-4CF7-A7AA-F09F4A763944"/>
<image href="COPY-GUID-8624163<9-37CD-4CF7-A7AA-F09F4A763944" scope="local"/>
<image href="COPY-GUID-8624163~9-37CD-4CF7-A7AA-F09F4A763944" scope="local"/>
</links>
以下是我得到的结果:
<error1>GUID-6A680D85-10FA-4BCC-B57D-B5138ABE6A59</error1>
<error1>GUID-1F14088D-4376-46FF-AE6F-937C2AAF5A43</error1>
<error1>GUID-BB4F234D-3584-4B92-B9CB-D91FBD913B8D#GUID-BB4F234D-3584-4B92-B9CB-D91FBD913B8D/MSCPDR1</error1>
<error1>GUID-6E03D2D4-3FA9-4437-8689-06B873FB56CB</error1>
<error1>GUID-C97E0253-73C1-4A27-B43E-7A913400BBB8</error1>
<error1>COPY-GUI'D-86241639-37CD-4CF7-A7AA-F09F4A763944</error1>
<error2>COPY-GUI'D-86241639-37CD-4CF7-A7AA-F09F4A763944</error2>
<error1>COPY-GUID-86241639-37CD-4CF7-A7AA-F09F4A763944</error1>
<error1>COPY-GUID/*+-862416}39-37CD-4CF7-A7AA-F09F4A763944</error1>
<error2>COPY-GUID/*+-862416}39-37CD-4CF7-A7AA-F09F4A763944</error2>
<error1>COPY-GUID-8624163{9-37CD-4CF7-A7AA-F09F4A763944</error1>
<error2>COPY-GUID-8624163{9-37CD-4CF7-A7AA-F09F4A763944</error2>
<error1>COPY-GUID-8624163<9-37CD-4CF7-A7AA-F09F4A763944</error1>
<error2>COPY-GUID-8624163<9-37CD-4CF7-A7AA-F09F4A763944</error2>
<error1>COPY-GUID-8624163~9-37CD-4CF7-A7AA-F09F4A763944</error1>
<error2>COPY-GUID-8624163~9-37CD-4CF7-A7AA-F09F4A763944</error2>
正如您所看到的,每个条目都有一个error1标记,而error2标记只适用于那些应该存在的情况。
为什么第一次比较不符合我认为应该有效的任何想法?
答案 0 :(得分:3)
以下无法正常使用:
<xsl:if test="not($invalid_characters='')">
<error>The error</error>
</xsl:if>
因为,空序列不等于任何东西(它也不等于另一个空序列)。试试,<xsl:value-of select="() = ()"/>
,您将获得false
。
因此,对于空序列,条件始终为true
。
为什么会这样?:
<xsl:if test="$invalid_characters!=''">
<error>The error</error>
</xsl:if>
是因为,对于空序列,它总是被评估为false
。尝试:<xsl:value-of select="() != ()"/>
,你会得到false
(空序列既不等也不等于任何东西)。
这里的序列,如果包含至少一个不是空字符串的项,则返回true
。因此,无法为空字符串或空字符串执行任务。
答案 1 :(得分:3)
您的变量是序列,包含零个,一个或多个字符串(每个字符串是否为空都取决于特定的正则表达式。)
空序列与空字符串不同;空序列和空字符串之间的比较总是返回false:
() = '' false
() != '' false
包含单个字符串的序列等同于该字符串(请参阅XPath Data Model),因此 可以是空字符串或(exclusive or)与空字符串不同:
('') = '' true
('') != '' false
('foo') = '' false
('foo') != '' true
两个序列是#34;相等&#34;如果他们至少有一个共同的项目,并且&#34;不同的&#34;如果他们至少有一个不同的项目。因此,两个序列可能 等于且不同。
这在比较多项序列和字符串时也适用,因为我们已经看到字符串等同于只包含该字符串的序列:
('', '') = '' true
('', '') != '' false
('foo', 'bar') = '' false
('foo', 'bar') != '' true
('foo', '') = '' true
('foo', '') != '' true
在处理序列时,检查$a != $b
并不等同于检查not($a = $b)