2013-05-20 239 views
0

我是XSLT的新手,所以我尋求幫助。我有許多XML文檔,其中以下是一個具有代表性的示例。這些文件分爲<sub-doc(n)>元素,其中又分爲<section>元素。在部分內是零或更多<heading>元素,以及一個或多個<paragraph>元素。我的目標是確保每個部分至多具有一個<heading>元素,方法是將具有多個標題的那些部分分成多個部分,每個部分各有一個標題。完成後,緊接在<heading>之後的<paragraph>元素必須與<heading>一起加入新的<section>。例如,請注意,在以下示例中,第一個<section><sub-doc1>有兩個<heading>元素。我需要將此元素分解爲兩個元素,每個元素都有其自己的<heading>和後續<paragraph>元素。如何將子節點拆分爲多個同級子節點,每個子節點都有一個子節點

<document> 
<sub-doc1> 
    <section> <!-- This section needs to be split --> 
    <heading>Subdoc1 first heading text</heading> 
    <paragraph>A lot of text</paragraph> 
    <paragraph>Yet more text</paragraph> 
    <paragraph>More text</paragraph> 
    ... 
    <heading>Subdoc1 second heading text</heading> 
    <paragraph>Even more text</paragraph> 
    <paragraph>Some text</paragraph> 
    ... 
    </section> 
    <section> 
    <paragraph>Even more text</paragraph> 
    ... 
    </section> 
</sub-doc1> 
<sub-doc2> 
    <section> 
    <heading>Subdoc2, first heading text</heading> 
    <paragraph>A lot of text here</paragraph> 
    <paragraph>Yet more text here</paragraph> 
    <paragraph>Yet more text here</paragraph> 
    ... 
    </section> 
</sub-doc2> 
</document> 

也就是說,轉換後的文檔需要看起來像這樣:

<document> 
<sub-doc1> 
    <section> <!-- This section got split into two sections --> 
    <heading>Subdoc1 first heading text</heading> 
    <paragraph>A lot of text</paragraph> 
    <paragraph>Yet more text</paragraph> 
    <paragraph>More text</paragraph> 
    ... 
    </section> 
    <section> <!-- This is a new section --> 
    <heading>Subdoc1 second heading text</heading> 
    <paragraph>Even more text</paragraph> 
    <paragraph>Some text</paragraph> 
    ... 
    </section> 
    <section> 
    <paragraph>Even more text</paragraph> 
    ... 
    </section> 
</sub-doc1> 
<sub-doc2> 
    <section> 
    <heading>Subdoc2, first heading text</heading> 
    <paragraph>A lot of text here</paragraph> 
    <paragraph>Yet more text here</paragraph> 
    <paragraph>Yet more text here</paragraph> 
    ... 
    </section> 
</sub-doc2> 
</document> 

注意某些部分沒有在所有<heading>元素。在這些情況下,這些部分應該保持不變。另外,有些章節只有一個<heading>。這些部分也應保持不變。而文檔中的其他內容應該保持不變。唯一需要進行的轉換是在文檔中任何地方的<section>有多個<heading>的情況下。

再說一遍,我是XSLT的新手,無法擺脫XSL的束縛,無法完成任務。感謝你的協助。

回答

-1

我能夠生成您正在尋找的輸出。對於我來說,這種類型的處理需要在XPath中使用前同步來抓取我正在查找的組元素,當它們存在於另一組元素之間時。

既然你也有過無頭部分路段,我不得不不同的方式處理那些部分。

<?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" version="1.0" encoding="UTF-8" indent="yes"/> 
    <xsl:template match="document"> 
    <document> 
     <!-- Select the sub-doc elements and print their names, then process their children --> 
     <xsl:for-each select="*"> 
     <xsl:element name="{local-name(.)}"> 
      <xsl:for-each select="section"> 
      <!-- For a section with 1 or more headings --> 
      <xsl:choose> 
       <xsl:when test="count(heading) &gt; 0"> 
       <!-- Print each section, heading and the paragraphs that follow --> 
       <xsl:for-each select="heading"> 
        <xsl:variable name="currentHeading" select="current()"/> 
        <section> 
        <heading> 
         <xsl:value-of select="."/> 
        </heading> 
        <!-- Pick paragraphs that follow current heading --> 
        <xsl:variable name="paragraphList" select="../paragraph[preceding-sibling::heading[1] = $currentHeading]"/> 
        <xsl:for-each select="$paragraphList"> 
         <paragraph> 
         <xsl:value-of select="."/> 
         </paragraph> 
        </xsl:for-each> 
        </section> 
       </xsl:for-each> 
       </xsl:when> 
       <xsl:otherwise> 
       <section> 
        <xsl:for-each select="paragraph"> 
        <paragraph> 
         <xsl:value-of select="."/> 
        </paragraph> 
        </xsl:for-each> 
       </section> 
       </xsl:otherwise> 
      </xsl:choose> 
      </xsl:for-each> 
     </xsl:element> 
     </xsl:for-each> 
    </document> 
    </xsl:template> 
</xsl:stylesheet> 

尼拉吉

0

stylesheet並不爲你問。它使用一個鍵來選擇對應於給定標題的所有paragraph元素。

我顯示輸出相當於去掉省略號您的樣品輸入。

請注意,此解決方案要求包含任何heading元素的所有 section元素都具有heading元素作爲第一個子元素。即在第一個heading之前沒有paragraph元素。 如果這個假設是錯誤的,那麼樣式表需要一個小的改變。

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:strip-space elements="*"/> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 

    <xsl:key name="paragraph-for-heading" match="paragraph" use="generate-id(preceding-sibling::heading[1])"/> 

    <xsl:template match="node()"> 
    <xsl:copy> 
     <xsl:apply-templates/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="section[heading]"> 
    <xsl:apply-templates select="heading"/> 
    </xsl:template> 

    <xsl:template match="heading"> 
    <section> 
     <xsl:copy> 
     <xsl:apply-templates/> 
     </xsl:copy> 
     <xsl:apply-templates select="key('paragraph-for-heading', generate-id())"/> 
    </section> 
    </xsl:template> 

</xsl:stylesheet> 

輸出

<document> 
    <sub-doc1> 
     <section> 
     <heading>Subdoc1 first heading text</heading> 
     <paragraph>A lot of text</paragraph> 
     <paragraph>Yet more text</paragraph> 
     <paragraph>More text</paragraph> 
     </section> 
     <section> 
     <heading>Subdoc1 second heading text</heading> 
     <paragraph>Even more text</paragraph> 
     <paragraph>Some text</paragraph> 
     </section> 
     <section> 
     <paragraph>Even more text</paragraph> 
     </section> 
    </sub-doc1> 
    <sub-doc2> 
     <section> 
     <heading>Subdoc2, first heading text</heading> 
     <paragraph>A lot of text here</paragraph> 
     <paragraph>Yet more text here</paragraph> 
     <paragraph>Yet more text here</paragraph> 
     </section> 
    </sub-doc2> 
</document> 
+0

感謝,鮑羅廷...!這很好用!對此,我真的非常感激。 – user2399942

相關問題