В настоящее время недокументированное ElementTree._namespace_map[uri] = prefix
является более старой версией Python (<1.3) для присвоения пространства имен более актуальной, документированной <a href="https://docs.python.org/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.register_namespace" rel="nofollow noreferrer">ElementTree.register_namespace(prefix, uri)
.Но даже этот метод не решает проблему с корнем, и в документах подчеркивается, что это назначение применяется глобально и заменяет любое предыдущее пространство имен или префикс:
xml.etree.ElementTree.register_namespace (prefix, uri) Регистрирует префикс пространства имен.Реестр является глобальным, и любое существующее сопоставление для данного префикса или URI пространства имен будет удалено. prefix - это префикс пространства имен. uri - это пространство имен uri.Теги и атрибуты в этом пространстве имен будут сериализованы с заданным префиксом, если это вообще возможно.
Для достижения желаемого результата и потому, что ваш XML немного сложен с несколькими значениями по умолчанию и непространства имен по умолчанию, рассмотрим XSLT , язык специального назначения для преобразования файлов XML.Python может запускать сценарии XSLT 1.0 со сторонним модулем lxml
(не встроенным etree
).Кроме того, XSLT является переносимым, поэтому сам код может выполняться на других языках (Java, C #, PHP, VB) и выделенных процессорах (например, Saxon, Xalan).
В частности, вы можете использоватьвременный префикс, например doc , для сопоставления пространства имен по умолчанию для родительского элемента нижнего уровня, VirtualInstrument и использования этого префикса для определения необходимых узлов.Все остальные элементы копируются как есть с шаблоном тождественного преобразования .Кроме того, поскольку вы добавляете элемент в пространство имен по умолчанию, вы можете назначить его с помощью тега xsl:element
.
XSLT (сохранить ниже как файл .xsl, специальный.XML-файл)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://www.ni.com/VirtualInstrument.xsd">
<xsl:output 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="doc:BlockDiagram">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:element name="Data" namespace="http://www.ni.com/VirtualInstrument.xsd"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Python
import lxml.etree as ET
# LOAD XML AND XSL
dom = ET.parse('Input.xml')
xslt = ET.parse('XSLTScript.xsl')
# TRANSFORM INPUT
transform = ET.XSLT(xslt)
newdom = transform(dom)
# OUTPUT RESULT TREE TO CONSOLE
print(newdom)
# SAVE RESULT TREE AS XML
with open('Output.xml','wb') as f:
f.write(newdom)
XSLT Demo