2013-04-02 39 views
1

我想結合一些XML文件,並保持它們之間的命名空間分離,並且遇到了一些問題。一切我已經能夠找到SO看起來像這樣(XSLT):XSLT命名空間前綴拋出處理器錯誤

<xsl:for-each select="sbn:fieldName"> 
    <xsl:element name="sbn:{name()}"> 
     <xsl:value-of select="text()"/> 
    </xsl:element> 
</xsl:for-each> 

我想保留在輸出sbn:空間前綴和該作品(至少,它的結果文檔中顯示出來),但儘管如此,處理器會拋出一堆警告,sbn:是一個無效的元素名稱......儘管事實上元素名稱實際上在輸出中正確地結尾爲sbn:fieldName

是否有其他方法可以做到這一點?我不想在每個元素上都有xmlns屬性。我使用Oxygen和Saxon6.5.5作爲處理器,儘管我在其他處理器上都遇到了同樣的錯誤(Xalan和libxslt Mac命令行版本)。 (你可能會問:如果輸出是好的,爲什麼我在意?好問題!我現在正在Oxygen的一個小文件上進行轉換,但目標是將一行百萬行的XML文件和使用xsltproc命令行做,所以,我沒有氧氣的內存開銷,因爲我需要所有的記憶,我可以得到運行轉換)

編輯:更多細節。

這是我正在嘗試處理的文件的修剪版本。

<collection xmlns="http://www.example.com/ns/foo"> 
    <record> 
     <fieldName> 
      <subA>some text</subA> 
      <subB>more text</subB> 
     </fieldName> 
    </record> 
</collection> 

還有一個樣式表的裁減版本,顯示了問題。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:sbn="http://www.example.com/ns/foo" 
    xmlns:bar="http://www.example.com/ns/bar" 
    version="1.0"> 

    <xsl:template match="//sbn:record"> 
    <xsl:for-each select="sbn:fieldName/node()"> 
     <xsl:element name="sbn:{local-name()}"> 
      <xsl:value-of select="text()"/> 
     </xsl:element> 
    </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 

這給xsltproc的錯誤:runtime error: file tiny.xslt line 8 element element xsl:element: The effective name 'sbn:' is not a valid QName.

回答

1

我覺得現在的問題是,你正在使用sbn:fieldName/node() - 因此錯誤 - 這也是文本節點,沒有名稱相匹配。

這個工作對我來說:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:sbn="http://www.example.com/ns/foo" 
    xmlns:bar="http://www.example.com/ns/bar" 
    version="1.0"> 

    <xsl:template match="//sbn:record"> 
    <xsl:for-each select="sbn:fieldName/*"> 
     <xsl:element name="{name()}" namespace="{namespace-uri()}"> 
      <xsl:value-of select="text()"/> 
     </xsl:element> 
    </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 
+0

這得到它,謝謝! (我不得不將元素名稱改爲'sbn:{name()}',但這沒什麼大不了的。)我剛剛忘記了什麼是非感性語言的XSLT,其中'*'選擇少於'node )'。 –

0

name()函數返回一個節點的名字與它的前綴,所以在這種情況下sbn:{name()}正在評估對sbn:sbn:fieldName

<xsl:element name="sbn:{local-name()}"> 

以下的或任一,如果你想重用在輸入期間使用的任何前綴:相反,如果你想確保前綴sbn:輸出使用,你應該使用這個,

<xsl:element name="{name()}"> 

<xsl:copy> 
    <!-- (Whatever content you want) --> 
</xsl:copy> 
+0

嗯......'本地名稱()'仍然給出了錯誤。看起來'name'和'local-name'的輸出之間沒有區別,如果我只是對它們做'value-of'。 –

+0

這很奇怪。在重新閱讀你的問題後,我發現你這樣做的理由是刪除'xmlns'屬性(它實際上不是一個屬性)。如果這就是原因,那麼我認爲你的方式是錯誤的。您能否向我們展示一個更大的XSLT示例和一些示例輸入,以及具有您希望避免的'xmlns'聲明的當前輸出? – JLRishe

+0

查看澄清編輯;希望這有助於。 –