簡體   English   中英

如何在xsl if中使用xsl變量

[英]How to use xsl variable in xsl if

我試圖將xsl變量中的值分配給我的xml文件中的新節點。 此代碼有效,但當“lbi:GetCoordinates(PVAL)”的值為空時添加一個空的PROP / 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()方法在作為xml命名空間添加的外部.Net程序集中。


使用這種方法有效:

<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表達式是不正確的,變量總是最終為空。

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

這幾乎是“正確的”。 唯一的問題是lbi:GetCoordinates(PVAL)周圍的報價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處理器是啞的並且調用該函數兩次,那么使用上面的clumsier代碼。

嘗試使用string-length(coords) > 0而不是您的條件。

如果你的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-clause更改為提前過濾,您也可以嘗試將if語句從not(string-length()=0)更改為string-length>0

我目前沒有環境來測試它,考慮包括你的source-xml,因為它對xslt的構造方式至關重要

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM