[英]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.