2012-11-18 17 views
3

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

如果你想知道:输出必须是普通的xt通常,只有$text变量的内容必须以HTML格式输出。这就是为什么我使用<![CDATA[]]

+0

提供的代码不应该产生任何结果,但会出现以下错误:“来自Saxonica Java版本1.6的Saxon 9.1.0.5J。0_31 Stylesheet编译时间:586毫秒 处理文件:/ C:/Program%20Files/Java/jre6/bin/marrowtr.xml 构建文件的目录树:/ C:/ Program%20Files/Java/jre6/bin/marrowtr。使用net.sf.saxon.tinytree.TinyBuilder 树XML内置在0毫秒 误差对marrowtr.xsl的第6行: XPTY0004:多个项目的序列不允许作为 XSL的@select属性:分析字符串(“(1)blah”,“(2)blah”,...) 转换失败:报告运行时错误 “ –

+0

@KelvinMackay,Understood。注意OP正在创建* tags *作为字符串 - 这是完全错误的,这些字符串可能不会被解释为HTML元素,而只是字符串。XSLT doesn'不处理“标签”,但有*节点*。因此,正确的转换会创建元素,而不是正好是这些元素的序列化的字符串。 –

回答

3

像这样简单

I. 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> 

wante d,正确的结果产生:

<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> 
+0

+1非常好:)删除我的回复赞成这个 – Kelvin

+0

@KelvinMackay,不客气。 –

+0

谢谢!这当然让我走上正轨。 – user1834166

0

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

(1)为XSLT 2.0溶液中的模板匹配条件可被简化为...

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

如此说来,对于XSL正则表达式:分析字符串应该保持原样。 (2)可能,这超出了问题的范围,但问题读取像html是预期的输出,所以应该向OP建议html xsl:output方法。