Как использовать переменную xsl в xsl, если - PullRequest
4 голосов
/ 27 октября 2010

Я пытаюсь присвоить значение из переменной xsl новому узлу в моем XML-файле.Этот код работает, но добавляет пустой узел PROP / PVAL, когда значение «lbi: GetCoordinates (PVAL)» пусто:

<xsl:template match="PROP" mode="Geocode">
<PROP NAME="Geocode">
    <PVAL>
      <xsl:value-of select="lbi:GetCoordinates(PVAL)"/>
    </PVAL>
 </PROP>
 </xsl:template>

Поскольку я не хочу пустых узлов, я пытаюсьдобавляйте новый узел только в том случае, если значение «lbi: GetCoordinates (PVAL)» не является пустым.Подход, который я пытаюсь сделать, - это присвоить значение переменной и проверить ее, как показано ниже.К сожалению, когда я делаю это, я не получаю новых узлов PROP, даже когда lbi: GetCoordinates (PVAL) возвращает непустое значение.

<xsl:template match="PROP" mode="Geocode">
<xsl:variable name="coords" select="'lbi:GetCoordinates(PVAL)'"/>
<xsl:if test="not(string-length(coords) = 0)">
  <PROP NAME="Geocode">
    <PVAL>
      <xsl:value-of select="coords"/>
    </PVAL>
  </PROP>
</xsl:if>
</xsl:template>

Может кто-нибудь указать мне правильное направление или предложить лучшийспособ достижения этого?

Исходный xml выглядит следующим образом:

<RECORD>
<PROP name="PostCode">
<PVAL>N11 1NN</PVAL>
</PROP>
</RECORD>

, а шаблон ссылается так:

<xsl:template match="RECORD">
<xsl:copy>
  <xsl:apply-templates select="PROP[@NAME='PostCode']" mode="Geocode"/>
</xsl:copy>

lbi: метод GetCoordinates () во внешней сборке .Net добавлен в виде пространства имен xml.


Использование этого подхода работает:

<xsl:template match="PROP[string-length(lbi:GetCoordinates(PVAL))>0]" mode="Geocode">
  <PROP NAME="Geocode">
    <PVAL>
      <xsl:value-of select="lbi:GetCoordinates(PVAL)"/>
    </PVAL>
  </PROP>

ПроблемаТеперь, когда метод lbi: GetCoordinates вызывается дважды, когда его нужно вызывать только один раз, исходный xml может содержать более 100 000 элементов, нуждающихся в геокодировании, так что это нетривиально.Это говорит мне о том, что выражение xsl: variable, которое я использовал ранее, неверно и переменная всегда заканчивается как пустая.

Ответы [ 3 ]

4 голосов
/ 27 октября 2010
<xsl:variable name="coords" select="'lbi:GetCoordinates(PVAL)'"/> 
<xsl:if test="not(string-length(coords) = 0)"> 

Это "почти" правильно.Единственная проблема - кавычки вокруг lbi:GetCoordinates(PVAL).Они преобразуют возвращаемое значение из функции расширения - просто в строку выражения, которое вызывает эту функцию.Поскольку длина этой строки, очевидно, больше, чем 0, тест во второй строке всегда будет верным.

С этого момента я предполагаю, что функция lbi:GetCoordinates() возвращает строку илиатомарное значение (не узел или набор узлов) , потому что вы ничего не сказали о типе возвращаемого значения функции, но это очень важно!

Вы хотите (обратите внимание, что кавычки сейчас отсутствуют!):

<xsl:variable name="coords" select="lbi:GetCoordinates(PVAL)"/> 
<xsl:if test="not(string-length(coords) = 0)"> 

** Но даже это немного неуклюже.

Решение : Используйте силуШаблон XSLT соответствует шаблонам и полностью избегает условной логики внутри шаблона:

<xsl:template match="PROP[string-length(lbi:GetCoordinates(PVAL))]"
     mode="Geocode">
  <PROP NAME="Geocode">                     
    <PVAL>                     
      <xsl:value-of select="lbi:GetCoordinates(PVAL)"/>                     
    </PVAL>                     
   </PROP>
 </xsl:template> 

Не беспокойтесь, что функция lbi:GetCoordinates(PVAL) вызывается дважды, потому что хороший оптимизирующий процессор XSLT вызовет ее только один раз.Вы всегда можете провести некоторые тесты и посмотреть, так ли это.

В худшем случае, если процессор XSLT не работает и дважды вызывает функцию, используйте приведенный выше неуклюжий код.

0 голосов
/ 27 октября 2010

если ваш source-xml выглядит примерно так:

<PROP>
  <lbi:GetCoordinates(PVAL)>sometext</lbi:Getcoordinates(PVAL>
</PROP>

это должно сработать:

<xsl:template match="PROP[string-length(lbi:GetCoordinates(PVAL))>0]" mode="Geocode">
    <PROP NAME="Geocode">
        <PVAL>
          <xsl:value-of select="lbi:GetCoordinates(PVAL)"/>
        </PVAL>
     </PROP>
</xsl:template>

Я изменил предложение match для ранней фильтрации, вы также можете просто попытаться изменить выражение if с not(string-length()=0) на string-length>0

В настоящее время у меня нет среды, чтобы протестировать ее, подумайте о включении вашего source-xml, поскольку крайне важно, как именно должен создаваться xslt

0 голосов
/ 27 октября 2010

Попробуйте использовать string-length(coords) > 0 вместо вашего состояния.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...