我正在从一个xml文件创建一个WordML文档,该文件的元素有时包含html格式的文本。
<w:p>
<w:r>
<w:t> html formatted content is in here taken from xml file! </w:t>
</w:r>
</w:p>这就是我的模板的设置方式。我有一个递归调用模板函数,可以对源xml内容进行文本替换。当遇到"<b>“标记时,我在CDATA中输出一个包含"</w:t></w:r><w:r><w:rPr><w:b/></w:rPr><w:t>”的字符串,以关闭当前运行并启动一个启用了粗体格式的新运行。当它到达"</b>“标记时,它用下面的CDATA字符串"</w:t></w:r><w:r><w:t>”替换它。
我想做的是使用XSL关闭run标记,并在不使用CDATA字符串插入的情况下开始新的运行。这个是可能的吗?
发布于 2008-10-30 17:38:23
使用WordML是很棘手的。使用XSLT将任意XML转换为WordML时的一个技巧是,在处理块时不要担心文本运行,而是直接创建一个与text()节点匹配的模板,并在那里创建文本运行。事实证明,Word并不关心您是否嵌套文本运行,这使得问题更容易解决。
<xsl:template match="text()" priority="1">
<w:r>
<w:t>
<xsl:value-of select="."/>
</w:t>
</w:r>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="para">
<w:p>
<xsl:apply-templates select="text() | *" />
</w:p>
</xsl:template>
<xsl:template match="b">
<w:r>
<w:rPr>
<w:b />
</w:rPr>
<w:t><xsl:apply-templates /></w:t>
</w:r>
</xsl:template>这避免了糟糕的XSLT技术,即直接将标记作为转义文本插入。您将以粗体标记作为嵌套文本运行结束,但正如我所说的,Word并不关心。如果使用这种技术,需要注意不要将模板应用到段落之间的空白处,因为它会触发文本模板并创建脱离上下文的运行。
发布于 2008-10-27 06:57:33
如果我能理解你的问题,我很可能会帮你。html是在CDATA部分中,还是被解析为输入文档的一部分(因此是格式良好的XML)?既然你谈到了“文本替换”,我就假设你把“html格式的内容”当作一个单独的字符串(CDATA),因此需要一个递归的调用模板函数来执行字符串替换。使用XSL匹配模板完成现在所做的工作的唯一方法是将html部分作为解析文档(输入文档)的一部分。在这种情况下,您只需匹配b标记并将其替换为适当的输出(同样:假设始终可以将其解析为有效的XML)。你的问题现在已经转移了.因为(如果我正确理解了您的问题)您要做的是关闭w:t和w:r元素,然后“重新打开”它们…这很困难,因为(正如您可能怀疑的那样)在XSLT中很难做到这一点(不能在模板A中创建一个元素,然后在模板B中关闭它)。你必须开始处理未转义的输出等,才能实现这一点。我现在做了很多假设,但这里有一个小例子来帮助你:
input.xml
<doc xmlns:w="urn:schemas-microsoft-com:office:word">
<w:p>
<w:r>
<w:t>before<b>bold</b>after</w:t>
</w:r>
</w:p>
</doc>convert_html.xsl
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/doc/w:p/w:r/w:t//b">
<xsl:value-of select="'</w:t></w:r><w:r><w:rPr><w:b/></w:rPr><w:t>'" disable-output-escaping="yes" />
<xsl:apply-templates select="@*|node()"/>
<xsl:value-of select="'</w:t></w:r><w:r><w:t>'" disable-output-escaping="yes" />
</xsl:template>
现在正在运行
xalan input.xml convert_html.xsl产生
<?xml version="1.0" encoding="UTF-8"?><doc xmlns:w="urn:schemas-microsoft-com:office:word">
<w:p>
<w:r>
<w:t>before</w:t></w:r><w:r><w:rPr><w:b/></w:rPr><w:t>bold</w:t></w:r><w:r><w:t>after</w:t>
</w:r>
</w:p>
</doc>我猜这就是你想要的。
希望这能对你有所帮助。
发布于 2008-10-27 14:30:45
根据您的描述,听起来您可以解析嵌入的html。如果是这样的话,简单地应用模板就可以做到你想要的效果。输出中的wordML可能不正确,但希望这会有所帮助。
示例输入:
<text>
<para>
Test for paragraph 1
</para>
<para>
Test for <b>paragraph 2</b>
</para>
</text>转换:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:w="http://foo">
<xsl:template match="/">
<w:p>
<w:r>
<xsl:apply-templates/>
</w:r>
</w:p>
</xsl:template>
<xsl:template match="para">
<w:t>
<xsl:apply-templates/>
</w:t>
</xsl:template>
<xsl:template match="b">
<w:rPr>
<w:b/>
</w:rPr>
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet> 结果:
<w:p xmlns:w="http://foo">
<w:r>
<w:t>
Test for paragraph 1
</w:t>
<w:t>
Test for <w:rPr><w:b /></w:rPr>paragraph 2
</w:t>
</w:r>
</w:p>https://stackoverflow.com/questions/234215
复制相似问题