我上一篇文章的反馈很有魅力,但我在系统中遇到了一些文件。输出如下。
<par def='1'>
<run>This is start of line one para one </run>
<run>text hotspot 1</run>
<run> remainder of line one<break/></run>
<run>This is line 2 </run>
<run>another hotspot </run>
<run>remainder of line 2 <break/></run>
</par>
是否可以使用XSLT生成以下输出?
<document>
<para>This is start of line one para one text hotspot 1 remainder of line one</para>
<para>This is line 2 another hotspot remainder of line 2</para>
</document>
即,<break/>
节点表示句子的结尾,但句子可能会在几个<run>
个节点上运行。
如果有人想知道,源数据是以Lotus Notes的DXL架构格式生成的。
到目前为止,我一直在使用第三方工具生成我的XSLT,我很乐意提供代码,但它不是很干净。
提前再次感谢您,成为此论坛的忠实粉丝。
DONO
答案 0 :(得分:1)
这个怎么样?它只会为<para>
中的第一个<run>
创建新的<par>
元素,如果前一个<par>
中有<break>
。
<xsl:template match="par">
<xsl:for-each select="run[preceding-sibling::run[1]/break or not(preceding-sibling::run)]">
<para>
<xsl:apply-templates select="."/>
</para>
</xsl:for-each>
</xsl:template>
<xsl:template match="run">
<xsl:value-of select="."/>
<xsl:if test="not(break)">
<xsl:apply-templates select="following-sibling::run[1]"/>
</xsl:if>
</xsl:template>
答案 1 :(得分:1)
虽然不是一种更好的方法,但它可以按你的方式工作..
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="par">
<document>
<para>
<xsl:apply-templates select="node()"/>
</para>
</document>
</xsl:template>
<xsl:template match="run">
<xsl:value-of select="."/>
<xsl:apply-templates select="break"/>
</xsl:template>
<xsl:template match="break">
<xsl:value-of select="'</para>'" disable-output-escaping="yes"/>
<xsl:value-of select="'<para>'" disable-output-escaping="yes"/>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分: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:key name="kPreceding" match="run"
use="generate-id((following::break|descendant::break)[1])"/>
<xsl:template match="par">
<document>
<xsl:apply-templates select="run/break"/>
</document>
</xsl:template>
<xsl:template match="break">
<para><xsl:apply-templates select="key('kPreceding', generate-id())/text()"/></para>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<par def='1'>
<run>This is start of line one para one </run>
<run>text hotspot 1</run>
<run> remainder of line one<break/></run>
<run>This is line 2 </run>
<run>another hotspot </run>
<run>remainder of line 2<break/></run>
</par>
会产生想要的正确结果:
<document>
<para>This is start of line one para one text hotspot 1 remainder of line one</para>
<para>This is line 2 another hotspot remainder of line 2</para>
</document>
<强>解释强>:
这是典型的XSLT 1.0位置分组解决方案。我们使用密钥来表达break
元素与其标识为组的所有run
元素之间的关系。