2012-08-13 68 views
1

我得到了幾個使用「父」子元素引用彼此的XML元素。並不是所有頂層元素都需要複製,所以我有一個固定的(main-)節uniqueNames列表,它需要被複制。分析樹的XML /結構(標籤引用彼此)

<xsl:variable name="mainSections">|news|sport|</xsl:variable> 

源XML主要欄目:

<section uniqueName="news"> 
</section> 

<section uniqueName="sport"> 
</section> 

<section uniqueName="travel"> 
</section> 

源XML子段:

其中小節應該在我的XSL複製mainsections名單

<section uniqueName="national_news"> 
    <parent uniqueName="news"/> 
</section> 

<section uniqueName="regional_news"> 
    <parent uniqueName="national_news"/> 
</section> 

<section uniqueName="city_news"> 
    <parent uniqueName="regional_news"/> 
</section> 

<section uniqueName="travel_europe"> 
    <parent uniqueName="travel"/> 
</section> 

<section uniqueName="holland"> 
    <parent uniqueName="travel_europe"/> 
</section> 

等等

因爲子部分容易在開發階段和生成我的XSL之間移動,更改或刪除,所以我需要動態確定是否有任何給定的子部分是主要部分之一的子部分。總計還有無數的小節。對要複製的小節列表進行硬編碼是可撤消的。

小節深度可以非常深,如下例所示:節「city_news」具有「regional_news」作爲父母,其中具有「national_news」作爲具有「news」作爲父母的父母,因此此部分需要複製,因爲它最終是「新聞」的孩子。 「荷蘭」部分的「旅行」頂級部分(根據「travel_europe」小節)不在要複製的列表中,因此需要忽略。

起初我試着檢查每個元素,如果父母是在列表中,但那只是愚蠢的,它只會讓我1級深。 我的最後一次嘗試是創建一個JavaScript,首先爲所有部分建立索引,然後分析結構,刪除與不在列表中的main部分相關的所有部分。 但是調用腳本也被證明是一個挑戰,因爲XSL無法自己調用javascript。

對於如何進行此操作,我有點無知......任何解決方案或建議?

源XML文檔是3500行,其中的信息對此問題無關緊要。問題是如何過濾主要部分小節的小節,或者:如何確定小節是否是指定主要部分的子節點。 考慮5提到的小節將被輸入,則輸出應該是:

<section uniqueName="national_news"> 
    <parent uniqueName="news"/> 
</section> 

<section uniqueName="regional_news"> 
    <parent uniqueName="national_news"/> 
</section> 

<section uniqueName="city_news"> 
    <parent uniqueName="regional_news"/> 
</section> 

由於

<section uniqueName="travel_europe"> 
    <parent uniqueName="travel"/> 
</section> 

<section uniqueName="holland"> 
    <parent uniqueName="travel_europe"/> 
</section> 

涉及「旅行」主部分,它是不在列表上要複製。

+0

請編輯問題並提供轉換的確切結果 - 如果未顯示,那麼這個問題的全部內容是什麼?還要提供源XML文檔 - 我們不應該猜測如何將小碎片放在一起。並建議不要說「等」 – 2012-08-13 12:47:37

+0

查看問題(底部)。等意味着有500個其他類似的聲明,要我提及他們? – user1595290 2012-08-13 12:57:30

回答

0

該轉化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:param name="pWanted" select="'|news|sport|'"/> 

<xsl:key name="kChildren" match="section" use="parent/@uniqueName"/> 

<xsl:template match="/*"> 
    <xsl:call-template name="getSections"> 
     <xsl:with-param name="pParents" select= 
     "section[contains($pWanted, concat('|',@uniqueName, '|'))]"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="getSections"> 
    <xsl:param name="pParents" select="/.."/> 

    <xsl:if test="$pParents"> 
    <xsl:copy-of select="$pParents"/> 
    <xsl:call-template name="getSections"> 
    <xsl:with-param name="pParents" 
     select="key('kChildren', $pParents/@uniqueName)"/> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 
</xsl:stylesheet> 

當施加到下面的XML文檔(沒有這樣的被提供!!!):

<t> 
    <section uniqueName="news"></section> 
    <section uniqueName="sport"></section> 
    <section uniqueName="travel"></section> 
    <section uniqueName="national_news"> 
     <parent uniqueName="news"/> 
    </section> 
    <section uniqueName="regional_news"> 
     <parent uniqueName="national_news"/> 
    </section> 
    <section uniqueName="city_news"> 
     <parent uniqueName="regional_news"/> 
    </section> 
    <section uniqueName="travel_europe"> 
     <parent uniqueName="travel"/> 
    </section> 
    <section uniqueName="holland"> 
     <parent uniqueName="travel_europe"/> 
    </section> 
</t> 

產生想要的(不完全指定在問題!),正確的結果

<section uniqueName="news"/> 
<section uniqueName="sport"/> 
<section uniqueName="national_news"> 
    <parent uniqueName="news"/> 
</section> 
<section uniqueName="regional_news"> 
    <parent uniqueName="national_news"/> 
</section> 
<section uniqueName="city_news"> 
    <parent uniqueName="regional_news"/> 
</section> 

說明

正確使用keys和遞歸。

+0

我對XSL相當陌生,以爲我在這個地方找到了它,但這超出了我的技能。仍然搞清楚你在那裏做了什麼,但這正是我所期待的。非常感謝你!過去兩天一直讓我頭疼...... – user1595290 2012-08-13 13:34:44

+0

@ user1595290,不客氣。 – 2012-08-13 13:50:37