2015-03-30 6 views
0

Я взял проект с файлами, созданными с помощью Mapforce. я читал что-то вроде: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(.) = '')))] 

Почему это делает бывший?

ответ

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> 

И непосредственно превратить его в Интернете 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 и строковое значение элемента контекста пусто

Принимать во внимание, что

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

означает

не позволяют случаи, когда xsi:nil является true и значение строки контекстного элемента пустой

Скорее всего, правильное ограничение: если xsi:nil = 'true', то элемент контекста должен быть пустым.

+0

Это для XSLT 1.0 – programaths