2013-10-04 73 views
0

很抱歉的格式,‘長期潛伏者,第一次海報’....捕獲「semi'-標記文本

我和另一個程序員一直在這一點,並試圖許多排列。我所想捕捉的是,去年「這是酒吧外無標記文本」行...... 不知道如何更好地描述標籤,但我收到的結構像這樣的XML塊:

<?xml version="1.0" encoding="UTF-8"?> 
    <text> 
    <inlineTag name="bar"> 
    <inlineTag name="text"> 
     <inlineTag name="strong"> 
      THIS IS A SIDEBAR BOX 
     </inlineTag> 
    </inlineTag>` 
    <break type="paragraph"/> 
    <break type="paragraph"/> 
    This is untagged text inside bar. 
    </inlineTag> 
    This is untagged text outside bar 
    </text> 

我運行鍼對此XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:template name="Untagged_Bar" match="text()[parent::node()/@name='bar']"> 
    <xsl:choose> 
     <xsl:when test="self::text() and string-length(.) &gt; 0"> 
      <xsl:element name="p"> 
       <xsl:attribute name="class" select="'k4text'"/> 
       <xsl:value-of select="."/> 
      </xsl:element> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:apply-templates/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
<xsl:template name="bold" match="//inlineTag[@name='strong']"> 
    <xsl:element name="strong"> 
     <xsl:value-of select="."/> 
    </xsl:element> 
</xsl:template> 
<xsl:template match="/"> 
    <root> 
    <xsl:apply-templates/> 
    </root> 
</xsl:template> 

而且我得到這個,這是我想要的幾乎什麼...

<?xml version="1.0" encoding="UTF-8"?> 
    <root> 
    <p class="k4text"> 
    </p> 
    <strong> 
     THIS IS A SIDEBAR BOX 
     </strong> 
     <p class="k4text"> 
     </p> 
    <p class="k4text"> 
    </p> 
    <p class="k4text"> 
    This is untagged text inside bar. 
    </p> 
    This is untagged text outside bar 
    </root> 

我要的是更多類似這樣的:

<?xml version="1.0" encoding="UTF-8"?> 
    <root> 
     <p class="k4text"> 
     <strong> 
     THIS IS A SIDEBAR BOX 
     </strong> 
     </p> 
     <p class="k4text"> 
     This is untagged text inside bar. 
     </p> 
     <p class="k4text"> 
     This is untagged text outside bar 
     </p> 
    </root> 

我缺少什麼?我有另一個XSLT傢伙在這裏工作看看吧,我們嘗試了很多排列組合,這是我們可以得到的最接近,但我們仍然不能說最後

<p class="k4text"> 
    This is untagged text outside bar 
    </p> 

出來正確的......任何想法/幫助/建議非常感謝!

+0

我編輯了我的答案,以提供不同的,更有效的解決方案。 –

回答

0

這裏是我的建議:

<xsl:stylesheet 
    version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output indent="yes"/> 

<xsl:template match="/"> 
    <root> 
    <xsl:apply-templates select="//text()[normalize-space()]"/> 
    </root> 
</xsl:template> 

<xsl:template match="text()"> 
    <xsl:variable name="current-text" select="."/> 
    <xsl:apply-templates select="/*" mode="h"> 
    <xsl:with-param name="current-text" select="$current-text" tunnel="yes"/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="*" mode="h"> 
    <xsl:param name="current-text" tunnel="yes"/> 
    <xsl:apply-templates select="node()[descendant-or-self::node() intersect $current-text]" mode="h"/> 
</xsl:template> 

<xsl:template match="inlineTag[@name = 'strong']" mode="h"> 
    <xsl:param name="current-text" tunnel="yes"/> 
    <strong> 
    <xsl:apply-templates select="node()[descendant-or-self::node() intersect $current-text]" mode="h"/> 
    </strong> 
</xsl:template> 

<xsl:template match="*[@name = 'bar']" mode="h"> 
    <xsl:param name="current-text" tunnel="yes"/> 
    <p class="k4text"> 
    <xsl:apply-templates select="node()[descendant-or-self::node() intersect $current-text]" mode="h"/> 
    </p> 
</xsl:template> 

<xsl:template match="text()[not(ancestor::*[@name = 'bar'])]" mode="h"> 
    <p class="k4text"> 
    <xsl:value-of select="."/> 
    </p> 
</xsl:template> 

</xsl:stylesheet> 

它把輸入

<?xml version="1.0" encoding="UTF-8"?> 
    <text> 
    <inlineTag name="bar"> 
    <inlineTag name="text"> 
     <inlineTag name="strong"> 
      THIS IS A SIDEBAR BOX 
     </inlineTag> 
    </inlineTag> 
    <break type="paragraph"/> 
    <break type="paragraph"/> 
    This is untagged text inside bar. 
    </inlineTag> 
    This is untagged text outside bar 
    </text> 

到結果

<root> 
    <p class="k4text"> 
     <strong> 
      THIS IS A SIDEBAR BOX 
     </strong> 
    </p> 
    <p class="k4text"> 
    This is untagged text inside bar. 
    </p> 
    <p class="k4text"> 
    This is untagged text outside bar 
    </p> 
</root> 

我覺得上面的解決方案是與所有這些node()[descendant-or-self::node() intersect $current-text]檢查貴。因此,我發佈一個不同的方法,簡單地計算節點,一旦我們需要重建每個文本節點:

<xsl:stylesheet 
    version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:output indent="yes"/> 

<xsl:template match="/"> 
    <root> 
    <xsl:apply-templates select="//text()[normalize-space()]"/> 
    </root> 
</xsl:template> 

<xsl:template match="text()"> 
    <xsl:variable name="nodes" select="ancestor-or-self::node() except /"/> 
    <xsl:apply-templates select="$nodes[1]" mode="h"> 
    <xsl:with-param name="remaining-nodes" select="$nodes[position() gt 1]" tunnel="yes"/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="*" mode="h"> 
    <xsl:param name="remaining-nodes" tunnel="yes"/> 
    <xsl:apply-templates select="$remaining-nodes[1]" mode="h"> 
    <xsl:with-param name="remaining-nodes" select="$remaining-nodes[position() gt 1]" tunnel="yes"/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="inlineTag[@name = 'strong']" mode="h"> 
    <xsl:param name="remaining-nodes" tunnel="yes"/> 
    <strong> 
    <xsl:apply-templates select="$remaining-nodes[1]" mode="h"> 
     <xsl:with-param name="remaining-nodes" select="$remaining-nodes[position() gt 1]" tunnel="yes"/> 
    </xsl:apply-templates> 
    </strong> 
</xsl:template> 

<xsl:template match="*[@name = 'bar']" mode="h"> 
    <xsl:param name="remaining-nodes" tunnel="yes"/> 
    <p class="k4text"> 
    <xsl:apply-templates select="$remaining-nodes[1]" mode="h"> 
     <xsl:with-param name="remaining-nodes" select="$remaining-nodes[position() gt 1]" tunnel="yes"/> 
    </xsl:apply-templates> 
    </p> 
</xsl:template> 

<xsl:template match="text()[not(ancestor::*[@name = 'bar'])]" mode="h"> 
    <p class="k4text"> 
    <xsl:value-of select="."/> 
    </p> 
</xsl:template> 

</xsl:stylesheet> 

輸出應該是相同的,但代碼應該是更有效的。