2012-12-06 60 views
2

我之前发布的反馈非常有用,但我遇到了以下系统中的一些文档。输出如下。基于子节点的检测创建新节点

<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

+2

XSLT 1.0或2.0?在2.0中,它非常简单,使用''。 –

回答

1

这是怎么回事?它仅为<par>中的第一个<run>创建新的<para>元素,并且其前面的<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

虽然不是它的工作你的方式优选的方法..

<?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="'&#60;/para&#62;'" disable-output-escaping="yes"/> 
    <xsl:value-of select="'&#60;para&#62;'" disable-output-escaping="yes"/> 
    </xsl:template> 
</xsl:stylesheet> 
+2

当没有其他方法可以实现你的目标时,你应该只考虑'disable-output-escaping'作为绝对最后的手段。它不受所有处理器的支持,例如,如果您使用API​​将输出生成为内存中的DOM树而不是磁盘上的文件,则不起作用。 –

+2

@IanRoberts,我尝试了一个替代现有的!由于现有的答案已达到最佳状态,我尝试了一种可靠的方法..这是当然不优选的。并且不建议:) – Enthusiastic

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元素和它标识为一个组的所有元素之间的关系。