如果在 xsl 中使用 xsl 变量 [英] How to use xsl variable in xsl if

查看:39
本文介绍了如果在 xsl 中使用 xsl 变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 xsl 变量中的值分配给我的 xml 文件中的新节点.此代码有效,但当 "lbi:GetCoordinates(PVAL)" 的值为空时,会添加一个空的 PROP/PVAL 节点:

I am trying to assign a value from an xsl variable to a new node in my xml file. This code works, but adds an empty PROP/PVAL node when the value of "lbi:GetCoordinates(PVAL)" is empty:

<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) 返回一个非空值.

As I don't want any empty nodes, I am trying to only add the new node only when the value of "lbi:GetCoordinates(PVAL)" is not empty. The approach I am trying is to assign the value to a variable and test that variable, as below. Unfortunately, when I do this I get no new PROP nodes, even when lbi:GetCoordinates(PVAL) returns a non-empty value.

<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>

谁能为我指出正确的方向,或者提出更好的方法来实现这一目标?

Can anyone point me in the right direction, or suggest a better way of achieving this?

源xml是这样的:

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

并且模板是这样引用的:

and the template is referenced thus:

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

lbi:GetCoordinates() 方法位于作为 xml 命名空间添加的外部 .Net 程序集中.

The lbi:GetCoordinates() method is in an external .Net assembly added as an xml namespace.

使用这种方法有效:

<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 表达式是不正确的,并且该变量总是以空结尾.

The problem now is that the lbi:GetCoordinates method is called twice when it only needs to be called once, the source xml can have 100,000+ elements that need geocoding so this is non-trivial. This suggests to me that the xsl:variable expression I used earlier is incorrect and the variable always ends up as empty.

推荐答案

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

这几乎"是正确的.唯一的问题是 lbi:GetCoordinates(PVAL) 周围的引号.这些将来自扩展函数的返回值转换为调用该函数的表达式的字符串.由于这个字符串的长度明显大于0,所以第二行的测试总是为真.

This is "almost" correct. The only problem is the quotes around lbi:GetCoordinates(PVAL). These convert the return value from an extension function-- just to the string of the expression that invokes this function. As the length of this string is obviously greater than 0, the test on the second line will allways be true.

从这里开始,我假设 lbi:GetCoordinates() 函数返回一个字符串或原子值(不是节点或节点集),因为您函数的返回类型没说,但是这个很重要!

From here on I suppose that the lbi:GetCoordinates() function returns a string or an atomic value (not a node or a node-set), because you haven't said anything about the return type of the function, but this is very important!

你想要(注意现在没有引号了!):

You want (note that the quotes are missing now!):

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

**但即使这样也有点笨拙.

**But even this is a little bit clumsy.

解决方案:利用 XSLT 模板匹配模式的强大功能,完全避免模板内部的条件逻辑:

Solution: Use the power of XSLT template match patterns and avoid the conditional logic inside the template altogether:

<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 处理器只会调用它一次.您可以随时进行一些测试,看看是否是这种情况.

Don't worry that the lbi:GetCoordinates(PVAL) function is called twice because a good optimizing XSLT processor will only call it once. You may always conduct some tests and see if this is the case.

在最坏的情况下,如果 XSLT 处理器是愚蠢的并且调用该函数两次,那么使用上面更笨拙的代码.

In the worst case, if the XSLT processor is dumb and calls the function twice, then use the clumsier code above.

这篇关于如果在 xsl 中使用 xsl 变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆