Как я могу, учитывая w3c DOM (реализация Java по умолчанию, в частности) изменить пространство имен каждый элемент/атрибут/узел в этом DOM? Эффективно, предпочтительно.
Я не думаю, что есть эффективное решение, которое также является надежным. Вы не можете просто переименовать что-то в корневой элемент. Рассмотрим эти документы:
doc1
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="urn:all" xmlns:f="urn:fleet" xmlns:m="urn:mission">
<f:starfleet>
<m:bold>
<f:ship name="Enterprise" />
</m:bold>
</f:starfleet>
</root>
doc2
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="urn:all">
<starfleet xmlns="urn:fleet">
<bold xmlns="urn:mission">
<ship xmlns="urn:fleet" name="Enterprise" />
</bold>
</starfleet>
</root>
Doc3
<?xml version="1.0" encoding="UTF-8"?>
<r:root xmlns:r="urn:all">
<r:starfleet xmlns:r="urn:fleet">
<r:bold xmlns:r="urn:mission">
<r:ship xmlns:r="urn:fleet" name="Enterprise" />
</r:bold>
</r:starfleet>
</r:root>
Эти три документа эквивалентны в пространств имён DOM. Вы можете запустить тот же namespaced XPath queries против любого из них.
Поскольку DOM позволяет вам точно указать, как узлы должны быть помещены в пространство имен, не существует единого одноразового вызова для изменения пространства имен. Вам нужно пройти DOM с учетом не только префикса и значений URI, но и их scope в любой момент времени.
Этот XSLT может быть использован с Transformer, чтобы изменить элементы, как urn:fleet
пространств имён, чтобы быть в пространстве имен urn:new
:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="urn:fleet" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="f:*">
<xsl:variable name="var.foo" select="local-name()" />
<xsl:element namespace="urn:new" name="{$var.foo}">
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Предостережения: дальнейшее тонкой настройки необходимо будет обрабатывать атрибуты пространств имён; dangling urn:fleet
объявления могут быть оставлены позади, что является грязным, но в значительной степени несущественным; вероятно, другие вещи, о которых я не думал.
XSL является, вероятно, самым простым решением, и должен работать в JAXP. Что вы пробовали, и как это случилось? – skaffman