2012-12-06 61 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元素和它標識爲一個組的所有元素之間的關係。