2015-01-15 167 views
1

如何在XSLT中動態生成名稱空間XML屬性?例如,我們可以使用不同的屬性,如attr1:fooattr2:bar有下面的XML文檔:如何在XSLT中動態生成名稱空間XML屬性?

<a xmlns="http://example.com/" 
    xmlns:attr1="http://example.com/attr1#" 
    xmlns:attr2="http://example.com/attr2#"> 
    <b attr1:foo=""/> 
    <b attr2:bar=""/> 
</a> 

假設我們要轉換文檔和更改所有屬性的值...。我們應該如何構建這些屬性?一個自然的選擇如何去做這個將是使用<xsl:attribute>。但是我們應該使用什麼QName作爲它的name屬性?函數name()可以將該屬性的QName作爲字符串返回。樸素XSL模板可能是這樣的:

<xsl:template match="@*"> 
    <xsl:attribute name="{name()}">...</xsl:attribute> 
</xsl:template> 

然而,由於name()返回QName字符串,這種解決方案需要已經通過xmlns在XSLT中預定義的命名空間前綴綁定(例如,xmlns:attr1="http://example.com/attr1#")。

然後我在想,如果使用的<xsl:attribute>namespace屬性是要走的路:

<xsl:template match="@*"> 
    <xsl:attribute name="{local-name()}" 
       namespace="{namespace-uri()}">...</xsl:attribute> 
</xsl:template> 

該解決方案似乎工作,但我認爲這是很難在XSLT的最佳實踐。你知道更好的解決方案嗎?

回答

2

這要看你怎麼知道的源文檔的結構信息:

  • 如果你知道使用的命名空間和它們的前綴綁定,然後 宣佈他們在您的樣式表,並使用你稱爲「天真XSL 模板「。

  • 否則複製命名空間(URI),如第二個模板中所示。


還要注意的是,你可以將二者結合起來,如下所示:

<xsl:template match="@*"> 
    <xsl:attribute name="{name()}" namespace="{namespace-uri()}">...</xsl:attribute> 
</xsl:template> 

對於某些處理器(例如撒克遜6.5),這將確保原始前綴在結果中重複使用;其他處理器(例如libxslt和Xalan)也會這樣做。

+0

我不知道命名空間前綴綁定事先。這就是爲什麼我想動態創建名稱空間屬性的原因。 – 2015-01-15 16:56:58

+0

然後我不知道比你的第二個模板更好的解決方案。你爲什麼認爲這不是最佳做法? – 2015-01-15 16:59:31

+0

好的,我只是不確定它是否是慣用的XSLT。我認爲有一個更簡單的方法來做到這一點。 – 2015-01-15 17:49:08