3

我有一个 XML 文件,其中除了有序列表之外的所有内容都结构良好。每个列表项都被标记为一个段落<p>,并手动添加枚举:(1)。我想从该源创建一个有效的 HTML 列表。

使用该xsl:matching-substring方法和正则表达式,我能够提取每个列表项,但我似乎找不到添加周围<ol>标签的方法。

这是一个例子:

XML 源:

<Content>
    <P>(1) blah</P>
    <P>(2) blah</P>
    <P>(2) blah</P>
</Content>

到目前为止我所拥有的:

<xsl:variable name="text" select="/Content/*/text()"/>
<xsl:analyze-string select="$text" regex="(\(\d+\))([^(]*)">
    <xsl:matching-substring>    
        <![CDATA[<li>]]><xsl:value-of select="regex-group(2)"/><![CDATA[</li>]]>
    </xsl:matching-substring>
</xsl:analyze-string>

输出:

<li>blah</li>
<li>blah</li>
<li>blah</li>

如果您想知道:通常输出必须是纯文本,只有$text变量的内容必须以 HTML 格式输出。这就是我使用<![CDATA[]].

4

2 回答 2

3

就这么简单

一、XSLT 2.0解决方案:

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

 <xsl:template match="/*">
  <ol>
    <xsl:apply-templates/>
  </ol>
 </xsl:template>

 <xsl:template match="P[matches(., '(^\(\d+\)\s*)(.*)')]">
    <li>
        <xsl:analyze-string select="." regex="(^\(\d+\)\s*)(.*)">
            <xsl:matching-substring>
              <xsl:value-of select="regex-group(2)"/>
            </xsl:matching-substring>
        </xsl:analyze-string>
    </li>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<Content>
    <P>(1) blah</P>
    <P>(2) blah</P>
    <P>(2) blah</P>
</Content>

产生了想要的正确结果:

<ol>
    <li>blah</li>
    <li>blah</li>
    <li>blah</li>
</ol>

二、XSLT 1.0 解决方案

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
  <ol>
    <xsl:apply-templates/>
  </ol>
 </xsl:template>

 <xsl:template match=
  "P[starts-with(.,'(')
   and
     floor(substring-before(substring(.,2), ')'))
    =
     substring-before(substring(.,2), ')')
    ]">
    <li>
         <xsl:value-of select="substring-after(., ') ')"/>
    </li>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于同一个 XML 文档(如上)时,会产生相同的正确结果

<ol>
   <li>blah</li>
   <li>blah</li>
   <li>blah</li>
</ol>
于 2012-11-18T21:58:22.343 回答
0

这并不是真正的解决方案,而是对 Dimitre 解决方案的建议略有改进。

(1) XSLT 2.0 解决方案的模板匹配条件可以简化为...

<xsl:template match="P[matches(., '^\(\d+\)')]">

话虽如此,xsl:analyze-string 的正则表达式应该保持原样。

(2) 可能,这超出了问题的范围,但问题看起来像 html 是预期的输出,因此应该向 OP 建议 html xsl:output 方法。

于 2012-11-19T04:22:01.743 回答