2

我已经稍微简化了这个问题,但我希望我仍然抓住了我的问题的本质。

假设我有以下简单的 XML 文件:

<main>
  outside1
  ===BEGIN===
    inside1
  ====END====
  outside2
  =BEGIN=
    inside2
  ==END==
  outside3
</main>

然后我可以使用以下 XSLT 2.0:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

<xsl:template match="text()">

  <xsl:analyze-string select="." regex="=+BEGIN=+">
     <xsl:matching-substring>
        <section/>
     </xsl:matching-substring>
     <xsl:non-matching-substring>
          <xsl:analyze-string select="." regex="=+END=+">  
             <xsl:matching-substring>
                <_section/>
             </xsl:matching-substring>
             <xsl:non-matching-substring>
                <xsl:value-of select="."/>
             </xsl:non-matching-substring>
          </xsl:analyze-string>
     </xsl:non-matching-substring>
  </xsl:analyze-string>

</xsl:template>

</xsl:stylesheet>

将其转换为以下内容:

<?xml version="1.0" encoding="UTF-8"?>
  outside1
  <section/>
    inside1
  <_section/>
  outside2
  <section/>
    inside2
  <_section/>
  outside3

以下是问题:

多个正则表达式

有没有更好的方法来匹配两个不同的正则表达式,而不是像上面所做的那样将它们嵌套在另一个中?

  • 如果它们不容易像这样嵌套怎么办?
  • 我可以有 XSL 模板来匹配和转换 regex 匹配text()吗?
    • 在这种情况下,我有两个模板,每个正则表达式一个
    • 如果可能,这将是理想的解决方案

正则表达式匹配的打开和关闭元素

显然,而不是:

<section/>
   inside
<_section/>

我最终真正想要的是:

<section>
   inside
</section>

那么你会怎么做呢?我不确定是否甚至可以在一个正则表达式匹配中打开一个元素并在另一个匹配中关闭它(即如果没有匹配更接近怎么办?结果将不是格式良好的 XML!),但它似乎这项任务非常典型,必须有一个惯用的解决方案。

注意:我们可以假设部分不会重叠,因此也不会嵌套。我们还可以假设它们总是成对出现。


附加信息

所以本质上我正在尝试完成 Perl 中简明扼要的事情:

s/=+BEGIN=+/<section>/
s/=+END=+/<\/section>/

我正在寻找一种在 XSLT 中执行此操作的方法,因为:

  • 就正则表达式匹配的上下文而言,它会更加健壮
    • (即它应该只转换text()节点)
  • 它在匹配各种 XML 实体方面也会更加健壮
4

1 回答 1

1

这种转变

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 exclude-result-prefixes="xs"
>
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="text()">
   <xsl:analyze-string select="." flags="mx"
    regex="=+BEGIN=+((.|\n)*?)=+END=+">

   <xsl:matching-substring>
    <section><xsl:value-of select="regex-group(1)"/></section>
   </xsl:matching-substring>

   <xsl:non-matching-substring>
    <xsl:value-of select="."/>
   </xsl:non-matching-substring>
 </xsl:analyze-string>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时

<main>
  outside1
  ===BEGIN===
    inside1
  ====END====
  outside2
  =BEGIN=
    inside2
  ==END==
  outside3
</main>

产生想要的结果

<main>
  outside1
  <section>
    inside1
  </section>
  outside2
  <section>
    inside2
  </section>
  outside3
</main>
于 2010-06-26T15:55:01.110 回答