2010-06-06 74 views
2

尋求使用XSLT來轉換我的XML。示例XML如下:使用XSLT重構XML節點

<root> 
<info> 
    <firstname>Bob</firstname> 
    <lastname>Joe</lastname> 
</info> 
<notes> 
    <note>text1</note> 
    <note>text2</note> 
</notes> 
<othernotes> 
    <note>text3</note> 
    <note>text4</note> 
</othernotes> 

我在尋找提取所有「筆記」元素,並讓他們父節點下的「注意事項」。

我在尋找的結果如下:

<root> 
<info> 
    <firstname>Bob</firstname> 
    <lastname>Joe</lastname> 
</info> 
<notes> 
    <note>text1</note> 
    <note>text2</note> 
    <note>text3</note> 
    <note>text4</note> 
</notes> 
</root> 

我試圖用的是讓我來提取我的「筆記」的XSLT,但我想不通我怎麼能將它們重新包裝在「筆記」節點中。

下面是我使用的XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="notes|othernotes"> 
     <xsl:apply-templates select="note"/> 
    </xsl:template> 
    <xsl:template match="*"> 
    <xsl:copy><xsl:apply-templates/></xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

我與上面的XSLT得到的結果是:

<root> 
<info> 
    <firstname>Bob</firstname> 
    <lastname>Joe</lastname> 
</info> 
    <note>text1</note> 
    <note>text2</note> 
    <note>text3</note> 
    <note>text4</note> 
</root> 

感謝

回答

2

可以產生這樣的內容:

<xsl:element name="notes"> 
    <!-- inject content of notes element here using e.g. <xsl:copy> or <xsl:copy-of> --> 
</xsl:element> 

稍做修改上述方法也適用於在特定XML名稱空間中生成元素。 但是因爲你是不是想找來生成命名空間的元素存在一個快捷方式:

<notes> 
    <!-- inject content of notes element here using e.g. <xsl:copy> or <xsl:copy-of> --> 
</notes> 

在你的具體的例子,我會調整你的樣式表來執行以下操作:

<xsl:template match="root"> 
    <root> 
    <xsl:copy-of select="info"/> 
    <notes> 
     <xsl:copy-of select="*/note"/> 
    </notes> 
    </root> 
</xsl:template> 
+1

不錯,乾淨,+1。我想用來代替重新創建,這是我個人偏好的問題。另外,要創建特定命名空間中的元素,您可以輕鬆聲明一個前綴並使用它:''。 ''實際上只在元素名稱應該是動態時才需要。 – Tomalak 2010-06-06 21:08:36

1

你會尋找對於這樣的事情: -

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

<xsl:template match="/root"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()[local-name() != 'notes' and local-name() != 'othernotes'] 
    </xsl:copy> 
    <notes> 
    <xsl:apply-templates select="othernotes/note | notes/note" /> 
    </notes> 
</xsl:template> 

您可以控制根節點的結構。首先複製未命名爲「筆記」或「其他註釋」的根目錄下的所有內容。然後直接創建一個「notes」元素,然後合併所有在「othernotes」或「notes」元素下面的「note」元素。

+0

'select =「@ * | node()[not(self :: notes or self :: othernotes)]」';-)(儘管在這個例子中'select =「info」'會產生同樣的效果...... ) – Tomalak 2010-06-06 21:01:46

+0

@Tomalak:其實我確實有這個,但是把它改回到使用本地名稱,我想不出現在爲什麼。 @ user268396的 解決方案在一個非常具體的例子中起作用,我正在做最小的假設(其他兄弟可能會出現信息,信息可能包含一個不受此合併影響的音符元素等) – AnthonyWJones 2010-06-07 09:31:22

+0

這就是爲什麼我給+1解。我有一個類似的準備,但你更快,所以我沒有發佈它。 :) – Tomalak 2010-06-07 10:15:15