在Python中将名称空间放入不同的XML标记中
我在在Python中将名称空间放入不同的XML标记中,python,xml,xml-namespaces,elementtree,Python,Xml,Xml Namespaces,Elementtree,我在tmp/Program.ev3p中有一个xml文件: 我正在尝试使用以下代码对其进行修改: 将xml.etree.ElementTree作为ET导入 tree=ET.parse('tmp/Program.ev3p') root=tree.getroot() 名称空间={'http://www.ni.com/SourceModel.xsd': '' , 'http://www.ni.com/VirtualInstrument.xsd':'', 'http://schemas.microso
tmp/Program.ev3p
中有一个xml文件:
我正在尝试使用以下代码对其进行修改:
将xml.etree.ElementTree作为ET导入
tree=ET.parse('tmp/Program.ev3p')
root=tree.getroot()
名称空间={'http://www.ni.com/SourceModel.xsd': '' ,
'http://www.ni.com/VirtualInstrument.xsd':'',
'http://schemas.microsoft.com/winfx/2006/xaml/presentation':'',
'http://schemas.microsoft.com/winfx/2006/xaml':'x',
'clr命名空间:NationalInstruments.LabVIEW.FrontPanelRuntime;assembly=NationalInstruments.LabVIEW.FrontPanelRuntime':'fpruntime',
'clr命名空间:NationalInstruments.SourceModel.Designer;程序集=NationalInstruments.SourceModel':'模型',
}
对于uri,名称空间中的前缀。项()
ET._名称空间_映射[uri]=前缀
图=根[0][0][1]
elem=ET.Element(‘数据’)
附加图(元素)
write('tmp/Program.ev3p',“UTF-8”,xml\u声明=True)
运行代码后,我的xml文件包含:
我需要名称空间位于它们在原始文件中注册的标记中,而不是将它们全部放在
SourceFile
中,是否可以在python中实现这一点?目前,未记录的ElementTree.\u namespace\u map[uri]=prefix
是较旧的python版本(<1.3)用于将命名空间分配到更当前的、有文档记录的。但即使这种方法也不能解决根问题,文档强调这种分配适用于全局,并替换任何以前的名称空间或前缀:
xml.etree.ElementTree.register\u名称空间(前缀,uri)注册命名空间前缀。注册表是全局的,任何现有的 将创建给定前缀或命名空间URI的映射 远离的。前缀是名称空间前缀。uri是一个名称空间uri。标签 此命名空间中的属性将使用给定的 前缀,如果可能的话
<>为了实现您的预期结果,因为XML具有多个默认和非默认命名空间的复杂性,请考虑专用语言来转换XML文件。Python可以使用第三方模块运行XSLT1.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>
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)