【问题标题】:XSL analyze-string difficulty with tokenized strings标记化字符串的 XSL 分析字符串难度
【发布时间】:2016-12-02 19:14:52
【问题描述】:

我需要标记一个字符串,然后在每个标记上运行analyze-string。然而,这似乎是不可能的:

"XPTY0020: 子轴上下文项的必需项类型 是节点();提供的值具有项目类型 xs:string) 因为 分析字符串需要一个节点上下文”。

这让我发疯了,因为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 将第一个希腊词与&lt;greek&gt;&lt;/greek&gt; 包装起来。

我可以使用什么解决方法使analyze-string 处理令牌,即字符串,而不是节点?

提前非常感谢!

【问题讨论】:

标签: regex xml xslt xslt-2.0 tokenize


【解决方案1】:

我认为问题在于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}"

【讨论】:

  • 更具体地说,这里可能发生的情况是处理器已经看到{IsGreek},将花括号内的文本解释为 XPath 表达式,确定它表示child::IsGreek,然后抱怨,因为当上下文项是字符串时,child::IsGreek 毫无意义。
  • @michael.hor257k,我在那里看到了类似的错误消息以及无法加载某些与 Unicode 类相关的文件的警告,所以我认为问题在于 Saxon 的特定安装和配置.我可以在 oXygen 中使用 Saxon 9.6 以及从命令行使用 Saxon 9.7 HE 运行该代码。
  • @michael.hor257k 不,我无法解释。该站点声称使用的是 Saxon-HE 9.5.1.6,但他们可能已经对其进行了修改以减少执行不受信任的样式表带来的威胁。它拒绝所有块名称(所以它不是“Greek”与“GreekAndCoptic”的问题 - 块名称在 Unicode 3.2 中更改)。如果无法加载包含块详细信息的数据文件,我会收到一条消息。
  • 谢谢你们。太糟糕了,唯一一个像样的在线测试应用程序有这个缺陷 - 更不用说经常离线了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多