0

我接管了一个使用 Mapforce 生成的文件的项目。我读到了类似的东西:

*[local-name()='no_regnat' and namespace-uri()=''][not((not((translate(string(@xsi:nil), 'true ', '1') = '1')) and (string(.) = '')))]

好像可以这样写

no_regnat[not((boolean(@xsi:nil) and (string(.) = '')))]

为什么是前者?

4

1 回答 1

1

让我们首先考虑表达式的左侧,

*[local-name()='no_regnat' and namespace-uri()='']

no_regnat

在大多数情况下,它们的含义完全相同,但在非常特定的情况下,它们不会产生相同的结果序列:

如果您xpath-default-namespace在 XSLT 2.0 样式表中定义一个,则表达式不会提供相同的结果:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="www.no_regnat.com">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <results>
            <xsl:apply-templates/>
        </results>
    </xsl:template>

    <xsl:template match="*[local-name()='no_regnat' and namespace-uri()='']">
       <!--Or: template match="no_regnat"-->
        <xsl:copy-of select="."/>
    </xsl:template>

</xsl:stylesheet>

例如,测试上述内容,

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:r="www.no_regnat.com">
    <no_regnat n="1"/>
    <r:no_regnat n="2"/>
    <other xmlns="www.no_regnat.com">
        <no_regnat n="3"/>
    </other>
</root>

并直接在此处在线改造。

因此,我们需要查看这些表达式的上下文来确定 Mapforce 是否确实生成了过于冗长的代码。


然后,第二个谓词:

translate(string(@nil), 'true ', '1')

在我看来,这真的很奇怪。该translate()函数只适用于单个字符,这就是为什么作为第二个和第三个参数的字符串translate()通常具有相同长度的原因。第二个参数中的字符在第三个参数中没有对应的字符被转换为空字符串。

因此,该函数在这里所做的是将、和、和(空白)映射t到空。在这里更有用。1rueboolean()


但要小心这些谓词的语义:

[not((not((translate(string(@xsi:nil), 'true ', '1') = '1')) and (string(.) = '')))]

方法

不允许xsi:nilisfalse且上下文元素的字符串值为空的情况

然而

[not((boolean(@xsi:nil) and (string(.) = '')))]

方法

不允许xsi:nilistrue且上下文元素的字符串值为空的情况

最有可能的是,正确的约束是:如果xsi:nil = 'true',则上下文元素必须为空。

于 2015-03-30T15:52:16.123 回答