2017-06-12 30 views
0

文字版XSLT分析mixedContent的字符串分割部分插入新元素

XML Source包含mixedContent-元素命名为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> 

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

任何帮助表示赞赏。

+0

那么当你需要提取计数器时,如果'paragraph'元素的第一个子节点是一个以四种模式之一开始的文本节点?或者也可以有一个像“(1) ......”这样的子元素的计数器,需要提取? –

+0

该数字总是纯文本,并且必须是第一个(文本的一部分)文本节点。 – uL1

回答

1

如果你只需要两个部分从第一个子节点是文本节点,那么我认为以下摘录做的是:

<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]"/>如果柜台与下列文字之间的空白不应显示在该段落中。

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