2016-02-11 18 views
1

我給出了XML作爲輸入,我無法控制結構。我需要將XML分解成多個部分並分別處理每個部分。下面是我要處理的文件的一個非常簡化的版本。使用XSLT 2.0將XML分解成零件

我試圖使用XSLT 2.0的分組功能通過使用<breakEle>標記作爲部分邊界來分解此XML。 <breakEle>也可以出現在任何級別。我試圖用XSLT 2.0做甚麼可能?我已經成功地使用Muenchian分組來完成XSLT 1.0,但是如果可以的話,我想遠離這一點。

樣品輸入:

<item class="poem"> 
    <div> 
     <div> 
      <p>paragraph 1</p> 
      <breakEle groupNum="1"/> 
     </div> 
     <div> 
      <p>Paragraph in another div.</p> 
     </div> 
     <breakEle groupNum="2"/> 
     <div> 
      <div> 
       <h4>header</h4> 
       <p>1st line</p> 
       <p>2nd line</p> 
       <br/> 
       <p>3rd line</p> 
       <p>4th line</p> 
       <page n="100"/> 
       <p>5th line</p> 
      </div> 
      <breakEle groupNum="3"/> 
     </div> 
    </div> 
</item> 

我正在努力工作以:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" 
    exclude-result-prefixes="xs xd" 
    version="2.0"> 
    <xsl:template match="/"> 
     <newRoot> 
      <xsl:copy> 
       <xsl:for-each-group select="*" group-ending-with="breakEle"> 
        <div num="{@groupNum}"> 
         <xsl:copy-of select="current-group()"/> 
        </div> 
       </xsl:for-each-group> 
      </xsl:copy> 
     </newRoot> 
    </xsl:template> 
</xsl:stylesheet> 

想有這樣的事情結束了:

<newRoot> 
    <div num="1"> 
     <p>paragraph 1</p> 
    </div> 
    <div num="2"> 
     <p>Paragraph in another div.</p> 
    </div> 
    <div num="3"> 
     <h4>header</h4> 
     <p>1st line</p> 
     <p>2nd line</p> 
     <br/> 
     <p>3rd line</p> 
     <p>4th line</p> 
     <page n="100"/> 
     <p>5th line</p> 
    </div> 
</newRoot> 
+0

什麼是這裏預期的結果? - 「*我已經成功使用Muenchian分組完成XSLT 1.0 *」爲什麼不張貼? –

+0

@ michael.hor257k對不起,我應該包括在第一次。我更新了它,謝謝! –

+0

該示例中的邏輯不明顯。爲什麼第三組不包含'div'? –

回答

0

下面的樣式表返回應用於給定示例時的預期結果。

它的工作原理是每個組只應包含葉元素。

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/item"> 
    <newRoot> 
     <xsl:for-each-group select=".//*[not(*)]" group-ending-with="breakEle"> 
      <div num="{current-group()[last()]/@groupNum}"> 
       <xsl:copy-of select="current-group()[not(self::breakEle)]"/> 
      </div> 
     </xsl:for-each-group> 
    </newRoot> 
</xsl:template> 

</xsl:stylesheet> 
+0

哇,那簡單嗎?是的,我沒有提到這些團體不僅包含葉元素。你的解決方案確實回答我發佈的問題如果這些團體不僅僅包含葉元素,那麼這種變化會有多大?如果這會更好,我可以問一個單獨的堆棧溢出問題。再次感謝! –

+0

我剛剛意識到你是幫助我使用XLST 1.0的人。只是想再次感謝你的時間。無論如何,我已經刪除了[not(*)]謂詞,但它會導致輸入的相同部分多次處理。我會一直搞亂它,如果我無法弄清楚,我會再次發佈。 –

+0

我們需要一個更好的問題定義 - 特別是當breakEle在中間分裂它時應該發生什麼。 –