XSLT 分析字符串将混合内容的一部分拆分为新元素



文本版本

XML Source包含一个名为 paragraph 的混合内容元素。大多数情况下,内容以括号中的数字开头,例如 (1) .该数字始终是第一个(部分(文本节点。

XML Target在名为 counter 的单独元素中处理此特定数字。

如何高效处理paragraph

示例数字掩码

(1)
(0...9)
[0...9]
{:digits:}

示例段落源

<paragraphs>
    <paragraph>(1) text <try>1</try> <italic>italic</italic> stuff</paragraph>
    <paragraph>[2] text <try>2</try> <italic>italic</italic> stuff</paragraph>
    <paragraph>{123} text <try>3</try> <italic>italic</italic> stuff</paragraph>
    <paragraph>text <try>4</try> <italic>italic</italic> stuff</paragraph>   
</paragraphs>

示例段落目标

<paragraphs>    
    <frame>
        <counter>(1)</counter>
        <paragraph>text <try>1</try> <italic>italic</italic> stuff</paragraph>
    </frame>
    <frame>
        <counter>[2]</counter>
        <paragraph>text <try>2</try> <italic>italic</italic> stuff</paragraph>
    </frame>
    <frame>
        <counter>{123}</counter>
        <paragraph>text <try>3</try> <italic>italic</italic> stuff</paragraph>
    </frame>
    <frame>
        <paragraph>text <try>4</try> <italic>italic</italic> stuff</paragraph>
    </frame>
 </paragraphs>

非(功能(部件

<xsl:template match="paragraph">
    <frame>
        <xsl:analyze-string select="." regex="(^[^s]+)"><!-- TODO: select digits instead of the first whitespace! -->
            <xsl:matching-substring>
                <xsl:element name="counter">
                    <xsl:value-of select="regex-group(1)" />
                </xsl:element>
            </xsl:matching-substring>
        </xsl:analyze-string>
        <paragraph>
            <xsl:apply-templates/><!-- TODO: everything but not the part of regex-group(1) + whitespace-character -->
        </paragraph>
    </frame>
</xsl:template>

我停止了这个模板的工作,因为也许有更好的解决方案来解决这个问题。

任何帮助,不胜感激。

如果您只需要从作为文本节点的第一个子节点中提取这两个部分,那么我认为以下内容可以做到这一点:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:param name="counter-pattern" as="xs:string">^(([0-9+])|[[0-9]+]|{[0-9]+})</xsl:param>
    <xsl:template match="@* | node()" mode="#all">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" mode="#current"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="paragraph">
        <frame>
            <xsl:apply-templates select="." mode="counter"/>
        </frame>
    </xsl:template>
    <xsl:template match="paragraph[node()[1][self::text()[matches(., $counter-pattern)]]]"
        mode="counter">
        <xsl:variable name="components" as="xs:string*">
            <xsl:analyze-string select="node()[1]" regex="{$counter-pattern}">
                <xsl:matching-substring>
                    <xsl:sequence select="."/>
                </xsl:matching-substring>
                <xsl:non-matching-substring>
                    <xsl:sequence select="."/>
                </xsl:non-matching-substring>
            </xsl:analyze-string>
        </xsl:variable>
        <counter>
            <xsl:value-of select="$components[1]"/>
        </counter>
        <xsl:copy>
            <xsl:value-of select="$components[2]"/>
            <xsl:apply-templates select="node()[position() gt 1]"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

如果计数器和以下文本之间的空格不应显示在段落中,则可能需要使用 <xsl:value-of select="replace($components[2], '^s+', '')"/> 而不是<xsl:value-of select="$components[2]"/>

以正则表达式为例,您可能还需要根据自己的需求进行调整。

相关内容

最新更新