2016-02-12 64 views
0

我想進行一個轉換,它可以根據屬性的值嵌套一組兄弟元素(outline-level)。需要幫助嵌套兄弟

這是輸入XML文件:

<text> 
    <para style="Heading 1" outline-level="1">Level 1</para> 
    <para xml:lang="en" style="Directive">Concept: 1</para> 
    <para xml:lang="en" style="Heading 2" outline-level="2">Level 2</para> 
    <para xml:lang="en" style="Directive">Concept: 2</para> 
    <para xml:lang="en" style="Heading 2" outline-level="2">Level 2</para> 
    <para xml:lang="en" style="Directive">Concept: 3</para> 
    <para xml:lang="en" style="Heading 3" outline-level="3">Level 3</para> 
    <para xml:lang="en" style="Directive">Concept: 4</para> 
    <para xml:lang="en" style="Heading 3" outline-level="3">Level 3</para> 
    <para xml:lang="en" style="Directive">Concept: 5</para> 
    <para xml:lang="en" style="Heading 1" outline-level="1">Level 1</para> 
    <para xml:lang="en" style="Directive">Concept: 6</para> 
    <para xml:lang="en" style="Heading 2" outline-level="2">Level 2</para> 
    <para xml:lang="en" style="Directive">Concept: 7</para> 
    <para xml:lang="en" style="Heading 3" outline-level="3">Level 3</para> 
    <para xml:lang="en" style="Directive">Concept: 8</para> 
</text> 

這是我想acheive什麼:

<root> 
    <para id="Concept: 1">Level 1 
     <para id="Concept: 2">Level 2</para> 
     <para id="Concept: 3">Level 2 
      <para id="Concept: 4">Level 3</para> 
      <para id="Concept: 5">Level 3</para> 
     </para> 
    </para> 
    <para id="Concept: 6">Level1 
     <para id="Concept: 7">Level 2 
      <para id="Concept: 8"/> 
     </para> 
    </para> 
</root> 

嵌套級別必須由@outline-level值來確定。嵌入的元素越深,數字越深。

任何想法將不勝感激。

+0

您可以使用XSLT 2.0處理器嗎?你有沒有看過類似的問題和答案像http://stackoverflow.com/questions/4547271/xslt-moving-a-grouping-html-elements-into-section-levels? –

回答

1

試試這個方法嗎?

XSLT 1.0

<xsl:stylesheet version="1.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:key name="child-paras" match="para" use="generate-id(preceding-sibling::para[@outline-level = current()/@outline-level - 1][1])" /> 

<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/text"> 
    <root> 
     <xsl:apply-templates select="para[@outline-level=1]"/> 
    </root> 
</xsl:template> 

<xsl:template match="para"> 
    <para id="{following-sibling::para[1]}"> 
     <xsl:value-of select="." /> 
     <xsl:apply-templates select="key('child-paras', generate-id())"/> 
    </para> 
</xsl:template> 

</xsl:stylesheet> 

當施加到您的示例輸入,其結果將是:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <para id="Concept: 1">Level 1<para id="Concept: 2">Level 2</para> 
     <para id="Concept: 3">Level 2<para id="Concept: 4">Level 3</para> 
     <para id="Concept: 5">Level 3</para> 
     </para> 
    </para> 
    <para id="Concept: 6">Level 1<para id="Concept: 7">Level 2<para id="Concept: 8">Level 3</para> 
     </para> 
    </para> 
</root> 

其中(比縮進差異其他)等同於您的預期的輸出 - 除了最後para其中id="Concept: 8"包含文本節點"Level 3" - 我相信這是正確的。

+0

謝謝@ michael.hor257k。我會標記你的答案是正確的。雖然我還有一個問題。我可以使用'' – Hairi

+0

爲什麼要拒​​絕使用密鑰的好處? –

+0

因爲可能有其他同級元素不包含'@ outline-level'或'para'。但這是我發佈這個問題後面臨的一個新問題。在我尋求幫助之前,我正在努力彌補自己的轉變。無論如何,再次感謝你,你幫了我很多。 – Hairi