2017-02-21 45 views
0

我有兩組XML文件,其中我想使用兩個輸入xml文件相同的XSL代碼。需要爲標題級別進行不對齊

我的第一個XML文件是:

<Body> 
<h1>Child1</h1> 
<p>Class1</p> 
<h2>Child2</h2> 
<p>Class2</p> 
<h3>Child3</h3> 
<p>Class3</p> 
<h4>Child4</h4> 
<p>Class4</p> 
</Body> 

XSL我用這個:

<xsl:template match="Body">  
<xsl:for-each-group select="*" group-starting-with="h1"> 
<topic> 
<xsl:attribute name="id">topic_<xsl:number count="h1 | h2 | h3 | h4"/></xsl:attribute> 
<title> 
<xsl:apply-templates select="node()"/> 
</title> 

<xsl:for-each-group select="current-group() except ." group-starting-with="h2"> 
<xsl:choose> 
<xsl:when test="self::h2"> 
<topic> 
<xsl:attribute name="id">topic_<xsl:number count="h1 | h2 | h3 | h4"/></xsl:attribute> 
<title> 
<xsl:apply-templates select="node()"/> 
</title> 

<xsl:for-each-group select="current-group() except ." group-starting-with="h3"> 
<xsl:choose> 
<xsl:when test="self::h3"> 
<topic> 
<xsl:attribute name="id">topic_<xsl:number count="h1 | h2 | h3 | h4"/></xsl:attribute> 
<title> 
<xsl:apply-templates select="node()"/> 
</title> 

<xsl:for-each-group select="current-group() except ." group-starting-with="h4"> 
<xsl:choose> 
<xsl:when test="self::h4"> 
<topic> 
<xsl:attribute name="id">topic_<xsl:number count="h1 | h2 | h3 | h4"/></xsl:attribute> 
<title> 
<xsl:apply-templates select="node()"/> 
</title> 
<body><xsl:apply-templates select="current-group() except ."/></body> 
</topic> 
</xsl:when> 
<xsl:otherwise> 
<body><xsl:apply-templates select="current-group()"/></body> 
</xsl:otherwise> 
</xsl:choose> 

</xsl:for-each-group> 
</topic>      
</xsl:when> 
<xsl:otherwise> 
<body><xsl:apply-templates select="current-group()"/></body> 
</xsl:otherwise> 
</xsl:choose> 

</xsl:for-each-group> 
</topic> 
</xsl:when> 
<xsl:otherwise> 
<body><xsl:apply-templates select="current-group()"/></body> 
</xsl:otherwise> 
</xsl:choose> 
</xsl:for-each-group> 
</topic> 
</xsl:for-each-group> 
</xsl:template> 

<xsl:template match="p"> 
<p><xsl:apply-templates/></p> 
</xsl:template> 

我得到的輸出象下面這樣:

<topic id="topic_1"> 
    <title>Child1</title> 
    <body> 
     <p>Class1</p> 
    </body> 
    <topic id="topic_2"> 
     <title>Child2</title> 
     <body> 
     <p>Class2</p> 
     </body> 
     <topic id="topic_3"> 
     <title>Child3</title> 
     <body> 
      <p>Class3</p> 
     </body> 
     <topic id="topic_4"> 
      <title>Child4</title> 
      <body> 
       <p>Class4</p> 
      </body> 
     </topic> 
     </topic> 
    </topic> 
</topic> 

現在我的第二個XML是(沒有h2):

<Body> 
<h1>Child1</h1> 
<p>Class1</p> 
<h3>Child3</h3> 
<p>Class3</p> 
<h4>Child4</h4> 
<p>Class4</p> 
</Body> 

我對第二個XML預期輸出會是這樣:

<topic id="topic_1"> 
    <title>Child1</title> 
    <body> 
     <p>Class1</p> 
    </body> 
    <topic id="topic_2"> 
     <title/> 
     <body/> 
     <topic id="topic_3"> 
     <title>Child3</title> 
     <body> 
      <p>Class3</p> 
     </body> 
     <topic id="topic_4"> 
      <title>Child4</title> 
      <body> 
       <p>Class4</p> 
      </body> 
     </topic> 
     </topic> 
    </topic> 
</topic> 

因爲我需要得到這個輸出。我如何改變上面提到的XSL代碼。我不需要爲此編寫新的代碼。我想編輯令人興奮的上面的XSL代碼。誰可以幫我這個事。

在此先感謝

+0

沒有,簡單,直接固定到現有的代碼顯然,例如,如果輸入結構不同,缺少元素,那麼''將會失敗,您既不能計數也不能組合元素存在。您是否考慮過採用兩步法,第一步添加缺少的元素,然後第二步應用您現有的代碼?您將必須認真指定並實施第一步。 –

+0

好的。感謝@MartinHonnen。我應該爲第二種方法創建單獨的模板還是可以使用任何其他可用的方法也提供給我。 – User501

+0

我建議執行第一個轉換步驟,在其他模式下添加缺失的元素,然後在該模式下處理輸入,將結果存儲在變量中,然後使用現有代碼處理變量內容。 –

回答

0

對於這個問題,答案就在這裏:

XSL我使用第二個XML是:

<xsl:template match="Body">  
<xsl:for-each-group select="*" group-starting-with="h1"> 
<topic> 
<xsl:attribute name="id">topic_<xsl:number count="h1 | h2 | h3 | h4"/></xsl:attribute> 
<title> 
<xsl:apply-templates select="node()"/> 
</title> 

<xsl:for-each-group select="current-group() except ." group-starting-with="h2"> 
<xsl:choose> 
<xsl:when test="self::h2"> 
<topic> 
<xsl:attribute name="id">topic_<xsl:number count="h1 | h2 | h3 | h4"/></xsl:attribute> 
<title> 
<xsl:apply-templates select="node()"/> 
</title> 

<xsl:for-each-group select="current-group() except ." group-starting-with="h3"> 
<xsl:choose> 
<xsl:when test="self::h3"> 
<topic> 
<xsl:attribute name="id">topic_<xsl:number count="h1 | h2 | h3 | h4"/></xsl:attribute> 
<title> 
<xsl:apply-templates select="node()"/> 
</title> 

<xsl:for-each-group select="current-group() except ." group-starting-with="h4"> 
<xsl:choose> 
<xsl:when test="self::h4"> 
<topic> 
<xsl:attribute name="id">topic_<xsl:number count="h1 | h2 | h3 | h4"/></xsl:attribute> 
<title> 
<xsl:apply-templates select="node()"/> 
</title> 
<body><xsl:apply-templates select="current-group() except ."/></body> 
</topic> 
</xsl:when> 
<xsl:otherwise> 
<body><xsl:apply-templates select="current-group()"/></body> 
</xsl:otherwise> 
</xsl:choose> 

</xsl:for-each-group> 
</topic>      
</xsl:when> 
<xsl:otherwise> 
<body><xsl:apply-templates select="current-group()"/></body> 
</xsl:otherwise> 
</xsl:choose> 

</xsl:for-each-group> 
</topic> 
</xsl:when> 
<xsl:otherwise> 
<body><xsl:apply-templates select="current-group()"/></body> 
</xsl:otherwise> 
</xsl:choose> 
</xsl:for-each-group> 
</topic> 
</xsl:for-each-group> 
</xsl:template> 

<xsl:template match="Body[not(h2)]">  
<xsl:for-each-group select="*" group-starting-with="h1"> 
<topic> 
<xsl:attribute name="id">topic_<xsl:number count="h1 | h3 | h4"/></xsl:attribute> 
<title> 
<xsl:apply-templates select="node()"/> 
</title> 

<xsl:for-each-group select="current-group() except ." group-starting-with="h3"> 
<xsl:choose> 
<xsl:when test="self::h3"> 
<topic> 
<xsl:attribute name="id">topic_<xsl:number count="h1 | h3 | h4"/></xsl:attribute> 
<title> 
<xsl:apply-templates select="node()"/> 
</title> 

<xsl:for-each-group select="current-group() except ." group-starting-with="h4"> 
<xsl:choose> 
<xsl:when test="self::h4"> 
<topic> 
<xsl:attribute name="id">topic_<xsl:number count="h1 | h3 | h4"/></xsl:attribute> 
<title> 
<xsl:apply-templates select="node()"/> 
</title> 


</topic>      
</xsl:when> 
<xsl:otherwise> 
<body><xsl:apply-templates select="current-group()"/></body> 
</xsl:otherwise> 
</xsl:choose> 

</xsl:for-each-group> 
</topic> 
</xsl:when> 
<xsl:otherwise> 
<body><xsl:apply-templates select="current-group()"/></body> 
</xsl:otherwise> 
</xsl:choose> 
</xsl:for-each-group> 
</topic> 
</xsl:for-each-group> 
</xsl:template> 

<xsl:template match="p"> 
<p><xsl:apply-templates/></p> 
</xsl:template>