2010-09-06 82 views
7

我想用以下命名空間轉換一個XML文件,但找不到一種方法使它與默認名稱空間一起工作,而不向輸出XML添加前綴。XSLT使用默認命名空間轉換XML而不添加前綴?

原始XML文件:

<pExport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://workflow.converga.com.au/compass"> 

我可以把它添加前綴到默認命名空間的工作(最後一個),但我怎麼可能輸出不添加前綴的XML,可以通過在.NET 4中使用XslCompiledTransform?

+0

你似乎意味着你可以*不*找到一種方法來使它與默認名稱空間一起工作,而無需向輸出XML添加前綴。那種方式不起作用?當你不添加前綴時,觀察到的行爲是什麼?你用XSLT標記了這個,所以你的意思是XSLT處理器不能識別工作流/羅盤命名空間中的pExport元素?需要更多信息。這可能有助於顯示樣式表的相關部分。 – LarsH 2010-09-06 06:38:02

+0

好問題(+1)。查看我的答案,瞭解具體示例和所用解決方案。 – 2010-09-06 17:11:41

+0

LarsH,是的我的意思是,如果不添加前綴,輸出XSLT將無法匹配具有默認名稱空間的節點(不帶標籤)。我正在尋找一種方法來匹配這些元素,而無需爲默認名稱空間添加我自己的前綴。 – 2010-09-06 21:51:41

回答

4

我可以把它加入了 前綴默認命名空間(該 最後一個)的工作,但我怎麼會輸出一個 XML沒有添加前綴,它是 可以通過使用XslCompiledTransform 。 NET 4?

這裏是一個具體的例子,如何做到這一點:

這種轉變

<xsl:stylesheet version="1.0" 
xmlns="http://workflow.converga.com.au/compass" 
xmlns:c="http://workflow.converga.com.au/compass" 
xmlns:ext="http://exslt.org/common" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
exclude-result-prefixes="c ext xsl"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pnewItem"> 
    <item name="wine"> 
    <price>3</price> 
    <quantity>5000</quantity> 
    </item> 
</xsl:param> 

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

<xsl:template match="c:item[last()]"> 
    <xsl:call-template name="identity"/> 
    <xsl:copy-of select="ext:node-set($pnewItem)/*"/> 
</xsl:template> 
</xsl:stylesheet> 

當XslCompiledTransform以下XML文檔應用:

<pExport xmlns="http://workflow.converga.com.au/compass"> 
<Goods> 
    <item name="tobacco"> 
    <price>5</price> 
    <quantity>1000</quantity> 
    </item> 
</Goods> 
</pExport> 

產生想(同一個XML文檔添加了一個新的項目),正確的結果

<pExport xmlns="http://workflow.converga.com.au/compass"> 
    <Goods> 
    <item name="tobacco"> 
     <price>5</price> 
     <quantity>1000</quantity> 
    </item> 
    <item name="wine"> 
     <price>3</price> 
     <quantity>5000</quantity> 
    </item> 
    </Goods> 
</pExport> 
+0

謝謝你,按照你的例子,我通過添加額外的默認命名空間而不需要前綴和「exclude-result-prefixex」選項。其實我並沒有完全理解你的代碼,以及他們是如何工作的(昨天剛學過XSLT)。例如,第一個代碼塊中的這些部分在做什麼? – 2010-09-06 21:40:58

+0

一個小問題,在輸出XML中,默認命名空間總是第一個,我可以將其更改爲最後一個,這是原始XML的位置。 – 2010-09-06 21:46:10

+0

@pstar:XSLT和XML W3C規範不要求屬性和名稱空間節點的任何特定順序。它們的相對順序是「依賴於實施」。這意味着根據您使用的具體XSLT處理器,您無法控制名稱空間聲明的排序,或者如果您有一定的控制權限,則此「功能」不可移植,並且不受其他XSLT處理器支持。 – 2010-09-06 22:37:59

1

您只需在XSLT中定義默認命名空間即可。如果你還用一個前綴定義之一,也是這樣你就可以選擇輕鬆輸入XML項目:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://workflow.converga.com.au/compass" xmlns:compass="http://workflow.converga.com.au/compass"> 
    <xsl:template match="compass:pExport"> 
    <pExport>...</pExport> 
    ... 

上面的模板會匹配對您輸入的XML元素 - 和創造的文字元素將在默認輸出命名空間(這是相同的命名空間)。

當然,你應該知道,在XML前綴是無關緊要的 - 兩個項目是相同的,如果它們具有相同的命名空間和本地名稱,即使兩個前綴爲一個命名空間中定義。

<element xmlns="http://test.com"></element> 
<ns01:element xmlns:ns01="http://test.com"></ns01:element> 

上述兩個元素是相同的,因爲它們具有相同的完全限定名稱。

+0

用於複製具有相同名稱空間的匹配元素,您不需要聲明輸出的默認名稱空間,'copy'指令也可以這種方式工作。 – 2010-09-06 13:31:37

+0

我覺得你說得對,前綴不應該影響命名空間。你的解決方案在這個意義上起作用。我正在尋找的是一種解決方案,不需要將我自己的前綴添加到默認名稱空間。 – 2010-09-06 21:58:44

+0

這個前綴在理論上是不相關的*。實際上,一些解析器不符合命名空間規範,但您仍然希望使用兼容的編寫器生成文檔。另外一些基於XML的標準的規範根本不使用命名空間。 – dolmen 2010-09-09 11:41:23

4

的關鍵是使用exclude-result-prefixes屬性stylesheet元素。

XSLT FAQthis section有一些很好的解釋。

+0

謝謝你Dolment指出我的信息。其實,我已經閱讀了一些XSLT,但沒有找到它。猜猜常見問題對我來說有點太多了。 – 2010-09-09 23:06:45

+0

感謝答案的好方法是點擊左側的向上箭頭進行投票。你能爲我做嗎? – dolmen 2010-09-27 08:47:16

+0

註冊參加XLT常見問題解答。 – Fortisimo 2013-03-27 16:50:45