Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 在XSLT中标记化混合内容_Xml_Xslt_Xslt 2.0_Tokenize - Fatal编程技术网

Xml 在XSLT中标记化混合内容

Xml 在XSLT中标记化混合内容,xml,xslt,xslt-2.0,tokenize,Xml,Xslt,Xslt 2.0,Tokenize,我有一个包含混合内容的元素。是否可以使用XSLT(2.0)将标记中的中的所有“单词”(例如,由模式\s+分隔)封装在中,并在必要时降入内联元素?例如,给定以下输入: <mixed> One morning, when <a>Gregor Samsa</a> woke from troubled dreams, he found himself transformed in his bed into a <b><c>hor

我有一个包含混合内容的元素
。是否可以使用XSLT(2.0)将
标记中的
中的所有“单词”(例如,由模式
\s+
分隔)封装在
中,并在必要时降入内联元素?例如,给定以下输入:

<mixed>
  One morning, when <a>Gregor Samsa</a>
  woke from troubled dreams, he found
  himself transformed in his bed into
  a <b><c>horrible vermin</c></b>.
</mixed>
(编辑:当前的3个答案均不满足此要求。)

  • 不能丢弃分割令牌。考虑在化学公式的上下文中,在<代码> <代码>标签中包装非系数数的类似任务。例如,
    2H2+O2
    变为
    2H2+O2
    。这不可能使用
    标记化
    函数,因为它只会丢弃分隔符。相反,我们可能不得不求助于
    分析字符串


  • 如果不是XSLT,那么执行此操作的最佳方法是什么?

    如果使用
    \S+
    上的
    分析字符串

    <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="mixed//text()">
            <xsl:analyze-string select="." regex="\S+">
                <xsl:matching-substring>
                    <w>
                        <xsl:value-of select="."/>
                    </w>
                </xsl:matching-substring>
                <xsl:non-matching-substring>
                    <xsl:value-of select="."/>
                </xsl:non-matching-substring>
            </xsl:analyze-string>
        </xsl:template>
    
    </xsl:transform>
    
    
    
    你得到

    <mixed>
      <w>One</w> <w>morning,</w> <w>when</w> <a><w>Gregor</w> <w>Samsa</w></a>
      <w>woke</w> <w>from</w> <w>troubled</w> <w>dreams,</w> <w>he</w> <w>found</w>
      <w>himself</w> <w>transformed</w> <w>in</w> <w>his</w> <w>bed</w> <w>into</w>
      <w>a</w> <b><c><w>horrible</w> <w>vermin</w></c></b><w>.</w>
    </mixed>
    
    
    一天早上,格雷戈·萨姆萨
    从烦恼的梦中醒来,他发现
    他自己在床上变成了一个男人
    可怕的害虫。
    

    是否确实要将尾随点与内联元素中的前一个
    害虫连接起来?

    AFAICT,这将在示例中提供预期结果:

    XSLT2.0

    <xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
    <xsl:strip-space elements="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="text()[ancestor::mixed]">
        <xsl:analyze-string select="." regex="\s+">
            <xsl:matching-substring>
                <xsl:value-of select="." />
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <w>
                    <xsl:value-of select="." />
                </w>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:template>
    
    </xsl:stylesheet>
    
    
    

    但是,我不理解您关于“以“单词”结尾的内联元素”的观点。例如,当一个单词的一部分被斜体化时,预期的结果是什么

    这个XSLT怎么样,它有一个额外的模板来处理紧跟在文本节点后面的元素,该节点只包含一个句号

    <xsl:stylesheet version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="node()|@*">
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
     </xsl:template>
    
     <xsl:template match="text()">
      <xsl:for-each select="tokenize(., '[\s]')[.]">
       <w><xsl:sequence select="."/></w>
      </xsl:for-each>
     </xsl:template>
    
     <xsl:template match="text()[normalize-space() = '.']" />
    
     <xsl:template match="node()[following-sibling::node()[1][self::text()][normalize-space() = '.']]">
      <w>
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
         <xsl:text>.</xsl:text>
      </w>
     </xsl:template>
    </xsl:stylesheet>
    
    
    .
    
    <代码> >我认为<代码>害虫> <代码>是一个单词,因为它不包含分隔符模式<代码> \s+< /代码>。但是,内联元素<代码> >代码>和代码> <代码>在前一个单词中打开,但在该单词的中间被关闭:<代码>害虫> >因此,仅在一个元素中包装<代码>害虫> <代码>,必须是内联元素<代码> >代码>和<代码> <代码>,这是几个单词的一部分,被拆分。我的帖子中已经有一个预期结果的例子:
    一个可怕的害虫。
    。请让我知道这是否有意义。如果我理解正确,建议的解决方案在这方面符合您的要求-尽管原因完全不同,即每个文本节点都是单独处理的。我相信您的解决方案包含空格,而不是单词,使用
    ,因为
    分析字符串中的
    regex
    参数是
    \s+
    。即使更改为
    \S+
    ,输出也会以
    害虫结束。
    “我相信您的解决方案包装的是空格,而不是单词”,现在已修复。-“输出以…”结束。我们需要更明确的规则。在此之前,如果句点是单词的一部分,那么单个句点就是一个字母单词。如果您希望每个文本节点也考虑前面/下一个节点,这将变得更加复杂。确实,这是一个复杂的问题。正确,我确实想加入尾随点。嗨,米迦勒,没有一个发布的答案已经解决了我的问题。那我该怎么办?我真的没有足够的代表来支付奖金。嗯,你需要更好地定义这个问题。如果他们不知道如何只用纸和笔以及一些明确的规则手动解决问题,那么没有人能够提供一个算法来解决问题。
    <mixed>
      <w>One</w> <w>morning,</w> <w>when</w> <a><w>Gregor</w> <w>Samsa</w></a>
      <w>woke</w> <w>from</w> <w>troubled</w> <w>dreams,</w> <w>he</w> <w>found</w>
      <w>himself</w> <w>transformed</w> <w>in</w> <w>his</w> <w>bed</w> <w>into</w>
      <w>a</w> <b><c><w>horrible</w> <w>vermin</w></c></b><w>.</w>
    </mixed>
    
    <xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
    <xsl:strip-space elements="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="text()[ancestor::mixed]">
        <xsl:analyze-string select="." regex="\s+">
            <xsl:matching-substring>
                <xsl:value-of select="." />
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <w>
                    <xsl:value-of select="." />
                </w>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:template>
    
    </xsl:stylesheet>
    
    <xsl:stylesheet version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="node()|@*">
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
     </xsl:template>
    
     <xsl:template match="text()">
      <xsl:for-each select="tokenize(., '[\s]')[.]">
       <w><xsl:sequence select="."/></w>
      </xsl:for-each>
     </xsl:template>
    
     <xsl:template match="text()[normalize-space() = '.']" />
    
     <xsl:template match="node()[following-sibling::node()[1][self::text()][normalize-space() = '.']]">
      <w>
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
         <xsl:text>.</xsl:text>
      </w>
     </xsl:template>
    </xsl:stylesheet>