我接手了一个用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(.) = '')))]
为什么要做前者?
答案 0 :(得分:1)
让我们首先考虑表达式的左侧,
*[local-name()='no_regnat' and namespace-uri()='']
和
no_regnat
在大多数情况下,它们的含义完全相同,但在非常具体的情况下,它们不会产生相同的结果序列:
如果在XSLT 2.0样式表中定义xpath-default-namespace
,则表达式不会提供相同的结果:
<?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>
并直接在线转换here。
因此,我们需要查看这些表达式的上下文,以确定Mapforce是否确实生成了过于冗长的代码。
然后,第二个谓词:
translate(string(@nil), 'true ', '1')
在我看来, 真的奇怪。 translate()
函数仅适用于单个字符,这就是作为translate()
的第二个和第三个参数的字符串通常具有相同的长度的原因。第二个参数中第三个参数中没有对应字符的字符将转换为空字符串。
所以,这里的功能是将t
映射到1
,映射r
,u
和e
以及 (空白)什么也没有。
boolean()
在这里更有用。
但请注意这些谓词的语义:
[not((not((translate(string(@xsi:nil), 'true ', '1') = '1')) and (string(.) = '')))]
装置
不允许
xsi:nil
为false
并且context元素的字符串值为空的情况
尽管
[not((boolean(@xsi:nil) and (string(.) = '')))]
装置
不允许
xsi:nil
为true
并且context元素的字符串值为空的情况
最有可能的是,正确的约束是:if xsi:nil = 'true'
,那么context元素必须为空。