2016-12-02 46 views
2

我需要標記字符串,然後在每個標記上運行analyze-string。然而,這似乎是不可能的:帶有標記化字符串的XSL分析字符串難度

「XPTY0020:所需項類型爲子軸 上下文項的是節點();提供的值具有項目類型的xs:串),因爲 分析串需要一個節點語境」。

這使我瘋了,因爲analyze-string應該,分析字符串,所以我不明白如何解決這個問題。

我(簡化)XML看起來是這樣的:

<?xml version="1.0" encoding="UTF-8"?> 
<rows> 
    <row> 
     <field name="def">1) ἀλλά sed, vero 2) καί et 3) а cum condicionali iunctum aequiparat 
      аште: 4) ἵνα ut chron.</field> 
    </row> 
    <row> 
     <field name="def">ἡλοῦν clavo figere</field> 
    </row> 
</rows> 

和我的樣式表看起來像這樣:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0"> 

    <xsl:strip-space elements="*"/> 
    <xsl:output omit-xml-declaration="no" indent="yes"/> 

    <xsl:template match="field[@name = 'def']"> 
     <entry> 
      <xsl:call-template name="sense"> 
       <xsl:with-param name="def" select="."/> 
      </xsl:call-template> 
     </entry> 
    </xsl:template> 

    <xsl:template name="sense"> 
     <xsl:param name="def"/> 
     <xsl:param name="separator" select="'\d{1,2}\)\s'"/> 

     <xsl:for-each select="tokenize(normalize-space($def), $separator)"> 
      <xsl:if test="string-length(.) > 0"> 
       <xsl:element name="sense"> 
        <xsl:attribute name="n"> 
         <xsl:value-of select="position() - 1"/> 
        </xsl:attribute> 
        <!--this is the problematic bit, because current() is 
        a string here -\- and, paradoxically, analyze-string 
        cannot deal with it--> 
        <xsl:analyze-string select="current()" 
         regex="^([\p{IsGreek}\p{IsGreekExtended}]+[\s]*[\p{IsGreek}\p{IsGreekExtended}]*)(.*$)"> 
         <xsl:matching-substring> 
          <greek> 
           <xsl:value-of select="regex-group(1)"/> 
           <xsl:value-of select="regex-group(2)"/> 
          </greek> 
         </xsl:matching-substring> 
         <xsl:non-matching-substring> 
          <xsl:value-of select="current()"/> 
         </xsl:non-matching-substring> 
        </xsl:analyze-string> 
       </xsl:element> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

沒有問題的analyze-string,上面的樣式將正確生成以下的輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<entry xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <sense n="1">ἀλλά sed, vero </sense> 
    <sense n="2">καί et </sense> 
    <sense n="3">а cum condicionali iunctum aequiparat аште: </sense> 
    <sense n="4">ἵνα ut chron.</sense> 
</entry> 
<entry xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <sense n="0">ἡλοῦν clavo figere</sense> 
</entry> 

樣式表使用tokenize()方法來分離多個感官。然後,對於每個已識別的感官,我想用analyze-string將第一個希臘語單詞用<greek></greek>包起來。

我可以使用什麼解決方法使analyze-string對令牌(即字符串)而不是節點起作用?

非常感謝提前!

+0

錯誤消息有誤導性。 ['xsl:analyze-string'指令以字符串形式輸入](https://www.w3.org/TR/xslt20/#analyze-string)。真正的問題在於你的正則表達式。 –

回答

3

我認爲問題是,regex屬性允許屬性值模板,這樣你的花括號需要加倍地說

regex="^([\p{{IsGreek}}\p{{IsGreekExtended}}]+[\s]*[\p{{IsGreek}}\p{{IsGreekExtended}}]*)(.*$)" 

,或者您需要一個變量例如外界定義圖案

<xsl:variable name="pattern">^([\p{IsGreek}\p{IsGreekExtended}]+[\s]*[\p{IsGreek}\p{IsGreekExtended}]*)(.*$)</xsl:variable> 

並使用regex="{$pattern}"

+0

更具體地說,這裏可能發生的事情是,處理器已經看到「{IsGreek}」,將大括號內的文本解釋爲XPath表達式,決定它意味着「child :: IsGreek」,然後抱怨,因爲「child :: IsGreek'當上下文項是一個字符串時沒有任何意義。 –

+0

@MichaelKay你可以在這裏解釋錯誤:http://xsltransform.net/jz1PuPo –

+0

@ michael.hor257k,我看到一個類似的錯誤消息,並伴隨着一個警告,一些與Unicode類相關的文件無法加載,所以我認爲薩克森的特殊安裝和配置存在問題。我可以在oXygen內部使用Saxon 9.6以及從命令行使用Saxon 9.7 HE來運行該代碼。 –