Как я могу, с учетом 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 с поддержкой пространства имен. Вы можете выполнять те же запросы XPath в пространстве имен для любого из них.
Поскольку 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>
Предостережения: для обработки атрибутов пространства имен потребуется дальнейшая настройка; можно оставить висячие urn:fleet
декларации, что является грязным, но в значительной степени несущественным; вероятно, другие вещи, о которых я не думал.