2013-05-03 62 views
0

我只能訪問xpath 1.0命令和函數。我需要將名稱空間聲明從根節點移動到開始使用該名稱空間的子節點。XSLT 1.0將命名空間移動到子節點

源XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Accounts xmlns:test="http:example.com/test1"> 
    <ParentAccount>10113146</ParentAccount> 
    <test1>test1</test1> 
    <test2>test2</test2> 
    <test:Siblings> 
     <test:CustomerNumber>10113146</test:CustomerNumber> 
     <test:CustomerNumber>120051520</test:CustomerNumber> 
    </test:Siblings> 
</Accounts> 

期望中的XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Accounts x> 
    <ParentAccount>10113146</ParentAccount> 
    <test1>test1</test1> 
    <test2>test2</test2> 
    <test:Siblings xmlns:test="http:example.com/test1"> 
     <test:CustomerNumber>10113146</test:CustomerNumber> 
     <test:CustomerNumber>120051520</test:CustomerNumber> 
    </test:Siblings> 
</Accounts> 

什麼好主意?

回答

2

下面介紹一種方法。

當這個XSLT:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Accounts xmlns:test="http:example.com/test1"> 
    <ParentAccount>10113146</ParentAccount> 
    <test1>test1</test1> 
    <test2>test2</test2> 
    <test:Siblings> 
    <test:CustomerNumber>10113146</test:CustomerNumber> 
    <test:CustomerNumber>120051520</test:CustomerNumber> 
    </test:Siblings> 
</Accounts> 

......想要的結果產生:

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

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

    <xsl:template match="Accounts"> 
    <Accounts> 
     <xsl:apply-templates /> 
    </Accounts> 
    </xsl:template> 

</xsl:stylesheet> 

......是對所提供的XML應用

<?xml version="1.0"?> <Accounts> <ParentAccount>10113146</ParentAccount> <test1>test1</test1> <test2>test2</test2> <test:Siblings xmlns:test="http:example.com/test1"> <test:CustomerNumber>10113146</test:CustomerNumber> <test:CustomerNumber>120051520</test:CustomerNumber> </test:Siblings> </Accounts> 

說明:

背後爲什麼這個作品的解釋與來自Namespaces in XML 1.0規範中的一個部分開始:

空間聲明中宣佈前綴的範圍從 擴展開始標記的開始其中它看起來在相應的結束標記 的末尾,排除具有相同NSAttName部分的任何內部聲明 的範圍。如果是空標籤,範圍 就是標籤本身。

此類名稱空間聲明適用於其範圍內所有元素和屬性 的名稱,其前綴與 聲明中指定的名稱相匹配。

簡而言之,這意味着當一個名稱空間在一個元素上聲明時,它實際上被定義爲用於該原始作用域下的所有元素。此外,如果一個名稱空間在一個元素上被使用而沒有首先在其他地方被定義,那麼適當的定義就發生在該元素上。

因此,使用您的文檔,我的XSLT,讓我們來看看如何發揮出來:

  1. 第一個模板 - The Identity Template - 將所有節點和屬性,是從源XML的結果XML。
  2. 第二個模板替換原來的<Accounts>元素;順便說一句,這個新的<Accounts>元素沒有定義http:example.com/test1命名空間。最後,此模板將模板應用於<Accounts>的所有子元素。
  3. 當處理器達到<test:Siblings>時,它會看到一個名稱空間,儘管它存在於原始XML中,但仍未在結果文檔中正確定義。因此,該定義被添加到<test:Siblings>
+0

Hello ABach,你能解釋一下爲什麼,或者提供解釋它的鏈接嗎?我在處理XSLT中的命名空間方面沒有經驗(我通常首先擺脫它們)。謝謝彼得 – Peter 2013-05-05 19:06:07

+0

@彼得 - 我添加了一個解釋。如果您還有其他問題,請告訴我。 – ABach 2013-05-05 21:12:25

+0

@ABACK:謝謝+1 – Peter 2013-05-13 06:59:10