从XML结构中的纯文本创建HTML列表

时间:2012-11-18 20:16:59

标签: html xml xslt xslt-2.0 plaintext

我有一个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[]]的原因。

2 个答案:

答案 0 :(得分: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>

<强> II。 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>

答案 1 :(得分:0)

这不是一个真正的解决方案,但建议在Dimitre的解决方案上略有改进。

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

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

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

(2)可能这不在问题的范围内,但问题如html是预期的输出,因此应该向OP建议html xsl:output方法。