2013-03-15 64 views
2

我知道這是從原來的問題不同,但它是一個思考過程中,我在想達到以下所需的結果:如何建立一個分層的部分/款/款「路徑」

XML輸入:

<section hangIndent="no" indent="arabic 1 digit" 
isProposedAmendment="no" label="2A"> 
<title>AAA</title> 
<body> 
BBB<subSection label="1"> 
    <body> 
    <para hangIndent="yes" indent="loweralpha 1 character" 
    isProposedAmendment="no" label="a"> 
     <body> 
     CCC 
     </body> 
    </para> 
    <para hangIndent="yes" indent="loweralpha 1 character" 
     isProposedAmendment="no" label="b"> 
     <body> 
     DDD 
     </body> 
    </para> 
    <para hangIndent="yes" indent="loweralpha 1 character" 
    isProposedAmendment="no" label="c"> 
     <body> 
     EEE 
     </body> 
    </para> 
    </body> 
</subSection> 
</body> 
<annotation isProposedAmendment="no"> 
FFFFF 
</annotation> 
</section> 

所需的輸出:我建立一個基於每個節點的標籤的xmlpath名稱,並將其插入到每個端點。

<nm:xmlpath name ="2A" /> 
<section hangIndent="no" indent="arabic 1 digit" 
isProposedAmendment="no" label="2A"> 
<title>AAA</title> 
<body> 
BBB 
<nm:xmlpath name ="2A 1" /> 
<subSection label="1"> 
    <body> 
    <nm:xmlpath name ="2A 1(a)" /> 
    <para hangIndent="yes" indent="loweralpha 1 character" 
isProposedAmendment="no" label="a"> 
     <body> 
     CCC 
     </body> 
    </para> 
    <nm:xmlpath name ="2A 1(b)" /> 
    <para hangIndent="yes" indent="loweralpha 1 character" 
    isProposedAmendment="no" label="b"> 
     <body> 
     DDD 
     </body> 
    </para> 
    <nm:xmlpath name ="2A 1(c)" /> 
    <para hangIndent="yes" indent="loweralpha 1 character" 
    isProposedAmendment="no" label="c"> 
     <body> 
     EEE 
     </body> 
    </para> 
    </body> 
</subSection> 
</body> 
<annotation isProposedAmendment="no"> 
FFFFF 
</annotation> 
</section> 
+1

但是按照這個速度,**沒有根元素**你的XML可能會變成無效的!你還好嗎? – 2013-03-15 12:02:36

+0

@ InfantPro'Aravind'它將擁有一個根的大型xml的測試數據。謝謝。 – luckyluke 2013-03-15 12:13:37

+0

如果有更多的上下文,請向我們展示轉換的輸入和包含根元素的所需輸出的示例,否則很難推薦代碼。 – 2013-03-15 12:16:34

回答

0

的基本做法是有一個具有label屬性的元素相匹配的模板,而這個元素插入之前從所有label構建的nm:xmlpath屬性你的父母,祖父母等

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
       xmlns:nm="urn:nm-namespace"> 

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

    <xsl:template match="*[@label]"> 
    <nm:xmlpath> 
     <xsl:attribute name="name"> 
     <xsl:apply-templates select="." mode="xmlpath" /> 
     </xsl:attribute> 
    </nm:xmlpath> 
    <xsl:call-template name="identity" /> 
    </xsl:template> 

    <!-- templates to construct the xmlpath, these should produce text nodes --> 

    <!-- general case - path is the enclosing path (if any), followed by space, 
     followed by our own @label --> 
    <xsl:template match="*" mode="xmlpath"> 
    <xsl:if test="ancestor::*[@label]"> 
     <xsl:apply-templates select="ancestor::*[@label][1]" mode="xmlpath" /> 
     <xsl:text> </xsl:text> 
    </xsl:if> 
    <xsl:value-of select="@label" /> 
    </xsl:template> 

    <!-- special case for para - no space after enclosing path, and surround 
     our label with() --> 
    <xsl:template match="para" mode="xmlpath"> 
    <xsl:apply-templates select="ancestor::*[@label][1]" mode="xmlpath" /> 
    <xsl:value-of select="concat('(', @label, ')')" /> 
    </xsl:template> 

</xsl:stylesheet> 
找到

爲了生成格式良好的XML,輸入文檔的根元素必須爲而不是具有label屬性 - 如果確實如此,我們會試圖在它之前插入nm:xmlpath,爲輸出文檔提供兩個根目錄,級別的元素。

0
<xsl:template match="/"> 
    <xsl:apply-templates select="//*"/> 
</xsl:template> 

<xsl:template match="*"> 
    <xsl:copy> 
    <xsl:value-of select="text()[1]"/> 
    </xsl:copy> 
</xsl:template> 

應該足夠了。

+0

OP已改變了問題,inturn已改變了要求!我非常喜歡你的答案,這個答案對於以前的需求來說很短暫和完美! – 2013-03-15 13:04:14