2010-12-15 42 views
1

我正在編寫的轉換必須從給定節點集組成一個以逗號分隔的字符串值。結果字符串必須根據輸入值中第一個字符的隨機(非字母)映射進行排序。使用字段子字符串的XSL關聯排序

我想出了這一點:

<?xml version="1.0" encoding="utf-8"?>  
<xsl:stylesheet  
     version="1.0"  
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
     xmlns:tmp="http://tempuri.org"  
     exclude-result-prefixes="tmp"  
>  
     <xsl:output method="xml" indent="yes"/> 

     <tmp:sorting-criterion>  
      <code value="A">5</code>  
      <code value="B">1</code>  
      <code value="C">3</code>  
     </tmp:sorting-criterion> 

     <xsl:template match="/InputValueParentNode">  
      <xsl:element name="OutputValues">  
      <xsl:for-each select="InputValue">  
        <xsl:sort select="document('')/*/tmp:sorting-criterion/code[@value=substring(.,1,1)]" data-type="number"/>  
        <xsl:value-of select="normalize-space(.)"/> 
        <xsl:if test="position() != last()">  
          <xsl:text>,</xsl:text>  
        </xsl:if> 
      </xsl:for-each>  
      </xsl:element>  
     </xsl:template>  
</xsl:stylesheet> 

它不工作,看起來像XPath的document('')/*/tmp:sorting-criterion/code[@value=substring(.,1,1)]如我所料不評估。我已經檢查了將substring(.,1,1)替換爲文字,並將其評估爲適當的值。

那麼,我是否遺漏了一些讓排序XPath表達式不按照我期望的那樣進行評估的問題,還是僅僅通過這種方式來強制執行?

如果無法創建可以工作的XPath表達式,是否有解決方法來實現我的目的?

注:我受限於XSLT的1.0

樣品輸入:

<?xml version="1.0" encoding="utf-8"?> 
<InputValueParentNode> 
     <InputValue>A input value</InputValue> 
     <InputValue>B input value</InputValue> 
     <InputValue>C input value</InputValue> 
</InputValueParentNode> 

預計輸出繼電器:

<?xml version="1.0" encoding="utf-8"?> 
<OutputValues>B input value,C input value,A input value</OutputValues> 
+0

你能提供例如輸入和預期的輸出? – wdebeaum 2010-12-15 15:35:54

+0

@wdebeaum:編輯的問題包括兩個。乾杯。 – 2010-12-15 15:52:06

回答

2

更換self::node()縮寫.,與current()功能。

更好的謂詞是:starts-with(normalize-space(current()),@value)

+0

使用'current()'是表達Antonio發佈表達式的正確方法。 – 2010-12-15 16:04:24

+0

@Alejandro:非常感謝,它的作品!我會仔細看看當前/上下文節點的區別:) – 2010-12-15 16:07:52

+0

@Antonio Perez:你很好。 'current()'是返回XSLT指令執行的上下文節點的XSLT函數。 '.'是XPath 1.0中的'self :: node()'的縮寫,意思是上下文節點,但這會隨着XPath表達式中的每一步而改變。 – 2010-12-15 16:12:57

0

除了根據Alejandro´s answer,改變變換我發現它最好使用XSL變量個映射數據,以避免如見於Dimitre´s answer to another related question虛設命名空間(TMP)的聲明。

我的最終實現:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet 
     version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
> 
     <xsl:output method="xml" indent="yes"/> 

     <xsl:template match="/InputValueParentNode"> 
      <xsl:variable name="sorting-map"> 
        <i code="A" priority="5"/> 
        <i code="B" priority="1"/> 
        <i code="C" priority="3"/> 
      </xsl:variable> 
      <xsl:variable name="sorting-criterion" select="document('')//xsl:variable[@name='sorting-map']/*"/> 

      <xsl:element name="OutputValues"> 
      <xsl:for-each select="InputValue"> 
        <xsl:sort select="$sorting-criterion[@code=substring(normalize-space(current()),1,1)]/@priority" data-type="number"/> 
        <xsl:value-of select="normalize-space(current())"/> 
        <xsl:if test="position() != last()"> 
          <xsl:text>,</xsl:text> 
        </xsl:if> 
      </xsl:for-each> 
      </xsl:element> 
     </xsl:template> 
</xsl:stylesheet>