Предположим, у вас есть этот XML-ввод:
<root xmlns="survivors">
<louis/>
<francis/>
</root>
Это означает, что каждый элемент находится под пространством имен по умолчанию, для которого его URI является "оставшимися в живых".
Как пишет Welbog, вы можете выбрать francis
элемент с:
/*/*[local-name()='francis']
или
/*[local-name()='root']/*[local-name()='francis']
Но, который также выбирает элемент francis
из следующих XML-входов:
<root xmlns="survivors" xmlns:n="no-survivors">
<louis/>
<n:francis/>
</root>
или
<root xmlns="survivors">
<louis/>
<francis xmlns="no-survivors"/>
</root>
Вы также можете усилить предикат с помощью некоторого URI пространства имен.Но кто?Параметром может быть пространство имен по умолчанию для корневого элемента, например:
/*/*[local-name()='francis'][namespace-uri()=namespace-uri(/*)]
Конечно, это делает выражение XPath очень многословным.
В XSLT 2.0 вы можете использовать атрибут xsl:xpath-default-namespace
, например:
<xsl:value-of select="/root/francis" xpath-default-namespace="survivors"/>
Но это не очень хорошо для вашего случая, потому что вы не знаете URI заранее.
EDIT : xsl:element
атрибуты AVT (шаблон значений атрибутов)) так что вам нужно это:
<xsl:element name="root" namespace="{$schema}"/>
Также я рекомендую вам объявить параметр как строковый тип данных (не RTF, как сейчас), что-то вроде:
<xsl:param name="schema" select="namespace-uri()"/>
РЕДАКТИРОВАТЬ 2 : Может быть, я не был ясен.Вам не нужно xsl:element/@namespace
в каждом случае.После вашего заявления о том, что каждый элемент находится только в одном пространстве имен по умолчанию, эта таблица стилей:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name()='bar']">
<xsl:element name="newbar" namespace="{namespace-uri()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
С этим вводом:
<root xmlns="whatever">
<foo/>
<bar/>
</root>
Вывод:
<root xmlns="whatever">
<foo></foo>
<newbar></newbar>
</root>
Edit 2 : я показывал вам, что когда вы копируете элемент, вы также копируете пространство имен, необходимое для расширения QName.Итак, если вы хотите преобразовать это:
<root xmlns="whatever">
<foo/>
<bar/>
</root>
В это:
<root xmlns="whatever">
<foo>
<bar/>
</foo>
</root>
Вы можете использовать эту таблицу стилей:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="*[1]|following-sibling::*[1]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>