2012-07-29 61 views
2



我正在轉換一些XML,將名爲alt-title的每個元素重命名爲Running_Head,前提是屬性alt-title-type等於「running-head」。

爲什麼XSL函數「ends-with」和「matches」都會引發錯誤?


所以,下面的代碼是使用行 <xsl:when test="starts-with(@alt-title-type, 'running-head')">哪些工作正常。然而,當我將其更改爲以下任一:

  • <xsl:when test="ends-with(@alt-title-type, 'running-head')">
  • <xsl:when test="matches(@alt-title-type, 'running-head')">

...這個錯誤被拋出:

Error:XSLTProcessor::transformToXml() [xsltprocessor.transformtoxml]: xmlXPathCompiledEval: 2 objects left on the stack.

所以,似乎函數starts-with正在工作,其中ends-withmatches不是。


這裏是我的XSL,使用 starts-with,這似乎是正常工作:

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

    <!-- Running_Head --> 
    <xsl:template match="@*|node()"> 
     <xsl:choose> 

      <xsl:when test="starts-with(@alt-title-type, 'running-head')"> 
       <xsl:element name="Running_Head"> 
        <xsl:apply-templates select="@*|node()"/> 
       </xsl:element> 
      </xsl:when> 

      <xsl:otherwise> 
       <xsl:copy> 
        <xsl:apply-templates select="@*|node()"/> 
       </xsl:copy> 
      </xsl:otherwise> 

     </xsl:choose> 
    </xsl:template> <!-- end of Running_Head --> 

</xsl:stylesheet> 

...這裏被轉換的XML:

<root-node> 
    <alt-title alt-title-type="running-head"> 
     This is working 
    </alt-title> 
    <alt-title alt-title-type="asdfng-head"> 
     asdfasdf 
    </alt-title> 
    <alt-title> 
     asdfasdf 
    </alt-title> 
    <alt-title alt-title-type="running-head"> 
     This is also working 
    </alt-title> 
</root-node> 


我正在測試這個在http://xslt.online-toolz.com/tools/xslt-transformation.phphttp://www.xsltcake.com/

+0

請發表您的錯誤代碼。其他一些代碼可能有用,但在解決方案中往往不相關。 – phihag 2012-07-29 21:04:03

+0

使用與上述相同的XML,然後在XSL中將 '結束 - 與'或'匹配'。 – 2012-07-29 21:08:39

+0

是的,當然 - 這就是我所做的重現異常。但是,如果您在第一時間發佈有問題的代碼而無需更改任何內容,則可以讓回答者更輕鬆。此外,你可以避免愚蠢的問題,如果發現錯字是錯誤的(例如,如果你鍵入'ends-wiith'並且沒有注意到它)。 – phihag 2012-07-29 21:18:04

回答

3

正如其他人所指出的,XSLT 1.0處理器不支持大多數XPath 2.0函數(如matches()ends-with())。

此外,在實現該電流要求變換並不需要在所有這些功能:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="alt-title[@alt-title-type='running-head']"> 
    <Running_Head> 
    <xsl:apply-templates select="@*|node()"/> 
    </Running_Head> 
</xsl:template> 
</xsl:stylesheet> 

當這個變換所提供的XML文檔施加:

<root-node> 
    <alt-title alt-title-type="running-head"> 
     This is working 
    </alt-title> 
    <alt-title alt-title-type="asdfng-head"> 
    asdfasdf 
    </alt-title> 
    <alt-title> 
    asdfasdf 
    </alt-title> 
    <alt-title alt-title-type="running-head"> 
    This is also working 
    </alt-title> 
</root-node> 

想要的,正確的生成是:

<root-node> 
    <Running_Head alt-title-type="running-head"> 
     This is working 
    </Running_Head> 
    <alt-title alt-title-type="asdfng-head"> 
    asdfasdf 
    </alt-title> 
    <alt-title> 
    asdfasdf 
    </alt-title> 
    <Running_Head alt-title-type="running-head"> 
    This is also working 
    </Running_Head> 
</root-node> 

說明

正確使用的模板,匹配模式和的identity rule壓倒一切。

+0

謝謝@Dimitre!這是一個清晰而簡單的解決方案,並感謝鏈接 - 我將研究這一點。 ;)另外,你能否在這個XSL中闡明''的用法?這會剝離線條之間的空間,而不是字符串本身的空白? – 2012-07-30 07:42:30

+1

@IanCampbell:不客氣。 'xsl:strip-space elements =「*」指示XML解析器放棄源XML文檔的所有隻包含空白的文本節點。這並不涉及任何非空白文本節點。 – 2012-07-30 11:32:01

+0

我該如何使用它:在XSLT 1.0中匹配(名稱(。),'grp')]「>'' Si8 2015-10-28 17:27:55

3

只有XPath 2.0具有matchesends-with函數。

在XPath 1.0,ends-with必須寫

$suffix = substring($target, string-length($target) - string-length($suffix) + 1) 

它沒有正則表達式的功能,但也許

包含($目標$子)

是你想要的,如果你有什麼沒有使用正則表達式元字符

+0

啊,謝謝你的澄清@Borodin!那麼,這是否是正確的語法? - '' – 2012-07-29 21:37:03

+1

' xsl:when test =''running-head'= substring(@ alt-title-type,string-length(@ alt-title-type) - string-length('running-head')+ 1)「>'I認爲。它看起來不錯!您可能希望將''running-head''放入一個變量中,以免錯誤輸入。 – Borodin 2012-07-29 21:58:16

+0

它所做的是從目標字符串的末尾取一個與匹配長度相等的子字符串,然後進行比較以查看它是否與匹配相等。 – Borodin 2012-07-29 22:29:50

0

您將模板聲明爲XSLT 1.0,但您使用的是2.0函數ends-withmatches。使用XSL 2.0處理器(或work around the missing functions),並將您的文檔聲明爲XSLT 2.0。

請注意,您收到的錯誤是由這些服務使用的XSL處理器的內部錯誤(它看起來像不能正確處理未定義的函數)。

+0

簡化了答案。如果downvoter能指出它有什麼問題,我會很感激。 – phihag 2012-07-29 21:14:53

+0

一個小小的批評(但我不是downvoter)是設置版本=「2.0」不是必不可少的,只要你用2.0處理器運行。 – 2012-07-29 21:50:46

相關問題