2016-07-12 73 views
0

我正在使用XLST 1.0並希望Transform XML to add 'nil' attributes to empty elements。我發現命名空間被添加到每個匹配元素,例如我的輸出如下: <age xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />當根節點可能有多個類型時向根節點添加名稱空間

我知道這是有效的,但我寧願它被添加到我的頂級節點。 How can I add namespaces to the root element of my XML using XSLT?

但是我有多個可能的根節點,所以我想我可以做這樣的事情:

<xsl:template match="animals | people | things"> 
    <xsl:element name="{name()}"> 
     <xsl:attribute name="xmlns:xsi">http://www.w3.org/2001/XMLSchema-instance</xsl:attribute> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 

但是我從Visual Studio得到一個錯誤「prexix的xmlns沒有定義」我碰到這個答案出來我不知道該怎麼做。

Here is my total XLST file它試圖做一些事情(它不會粘貼到SO出於某種原因):

  1. 變換不同類型的動物爲單一型
  2. 命名空間添加到根節點
  3. 添加xsi:nil = true空元素(注意,它們必須有沒有孩子不僅沒有文本,或者我的頂級節點被轉化)
+0

http://stackoverflow.com/help/be-nice –

回答

0

首先,一個名字速度聲明不是屬性,並且不能使用xsl:attribute指令創建。

可以使用xsl:copy-of在期望位置的 「手動」 插入一個命名空間聲明,例如:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="/*"> 
    <xsl:copy> 
     <xsl:copy-of select="document('')/xsl:stylesheet/namespace::xsi"/> 
     <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[not(node())]"> 
    <xsl:copy> 
     <xsl:attribute name="xsi:nil">true</xsl:attribute> 
     <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

然而,結果是相當的處理器相關的。例如,Xalan將忽略該指令,並像以前一樣在每個輸出的空節點處重複聲明。一般來說,您很少無法控制XSLT處理器如何串行化輸出。

另一種選擇是實際使用在根級別的命名空間聲明,說:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="/*"> 
    <xsl:copy> 
     <xsl:attribute name="xsi:nil">false</xsl:attribute> 
     <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[not(node())]"> 
    <xsl:copy> 
     <xsl:attribute name="xsi:nil">true</xsl:attribute> 
     <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

這工作與所有我曾與(因人而異)測試的處理器。

當然,最好的選擇是什麼都不做,因爲正如你所指出的,其差別純粹是美容。

相關問題