まず、式の左辺を考えてみましょう。
*[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 が実際に冗長すぎるコードを生成しているかどうかを判断する必要があります。
次に、2 番目の述語:
translate(string(@nil), 'true ', '1')
私の意見では、本当に奇妙です。このtranslate()
関数は単一の文字でしか機能しないため、translate()
通常、 の 2 番目と 3 番目の引数である文字列は同じ長さになります。3 番目の引数に対応する文字がない 2 番目の引数の文字は、空の文字列に変換されます。
つまり、ここで関数が行っているのは、t
へ1
のマッピングr
、u
およびe
および
(空白) を何もマッピングしないことです。boolean()
ここでははるかに便利です。
ただし、これらの述語のセマンティクスには注意してください。
[not((not((translate(string(@xsi:nil), 'true ', '1') = '1')) and (string(.) = '')))]
意味
であり、コンテキスト要素の文字列値が空の場合xsi:nil
は許可されませんfalse
一方
[not((boolean(@xsi:nil) and (string(.) = '')))]
意味
であり、コンテキスト要素の文字列値が空の場合xsi:nil
は許可されませんtrue
ほとんどの場合、正しい制約は次のとおりです。if の場合xsi:nil = 'true'
、コンテキスト要素は空でなければなりません。