带有标记化字符串的 XSL 分析字符串困难
XSL analyze-string difficulty with tokenized strings
我需要标记一个字符串,然后在每个标记上 运行 analyze-string
。然而,这似乎是不可能的:
"XPTY0020: Required item type of the context item for the child axis
is node(); supplied value has item type xs:string) because
analyze-string requires a node context".
这快把我逼疯了,因为 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
处理标记,即字符串,而不是节点?
非常感谢!
我认为问题是 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}"
.
我需要标记一个字符串,然后在每个标记上 运行 analyze-string
。然而,这似乎是不可能的:
"XPTY0020: Required item type of the context item for the child axis is node(); supplied value has item type xs:string) because analyze-string requires a node context".
这快把我逼疯了,因为 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
处理标记,即字符串,而不是节点?
非常感谢!
我认为问题是 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}"
.