我有一个像这样的xml:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:epp xmlns:ns0="urn:ietf:params:xml:ns:epp-1.0"
xmlns:ns1="http://epp.nic.ir/ns/contact-1.0">
<ns0:command>
<ns0:check>
<ns1:check>
<ns1:id>ex61-irnic</ns1:id>
<ns1:id>ex999-irnic</ns1:id>
<ns1:authInfo>
<ns1:pw>1487441516170712</ns1:pw>
</ns1:authInfo>
</ns1:check>
</ns0:check>
<ns0:clTRID>TEST-12345</ns0:clTRID>
</ns0:command>
</ns0:epp>
我想用python 3将其更改为:
<?xml version="1.0" encoding="UTF-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<check>
<check>
<id>ex61-irnic</id>
<id>ex999-irnic</id>
<authInfo>
<pw>1487441516170712</pw>
</authInfo>
</check>
</check>
<clTRID>TEST-12345</clTRID>
</command>
</epp>
我试图从lxml模块中删除带有objectify.deannotate的ns。 但它不起作用。 你能帮助我实现我的目标吗?
答案 0 :(得分:3)
这是Remove namespace and prefix from xml in python using lxml的组合,它显示了如何修改元素的命名空间,lxml: add namespace to input file显示了如何重置顶级命名空间映射。
代码有点hacky(我特别怀疑它是否是使用_setroot
方法的犹太教),但似乎有效:
from lxml import etree
inputfile = 'data.xml'
target_ns = 'urn:ietf:params:xml:ns:epp-1.0'
nsmap = {None: target_ns}
tree = etree.parse(inputfile)
root = tree.getroot()
# here we set the namespace of all elements to target_ns
for elem in root.getiterator():
tag = etree.QName(elem.tag)
elem.tag = '{%s}%s' % (target_ns, tag.localname)
# create a new root element and set the namespace map, then
# copy over all the child elements
new_root = etree.Element(root.tag, nsmap=nsmap)
new_root[:] = root[:]
# create a new elementtree with new_root so that we can use the
# .write method.
tree = etree.ElementTree()
tree._setroot(new_root)
tree.write('done.xml',
pretty_print=True, xml_declaration=True, encoding='UTF-8')
根据您的样本输入,这将在done.xml
中生成:
<?xml version='1.0' encoding='UTF-8'?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"><command>
<check>
<check>
<id>ex61-irnic</id>
<id>ex999-irnic</id>
<authInfo>
<pw>1487441516170712</pw>
</authInfo>
</check>
</check>
<clTRID>TEST-12345</clTRID>
</command>
</epp>
答案 1 :(得分:3)
考虑XSLT,这是专门用于转换XML文件的专用语言,例如删除命名空间。 Python的第三方模块lxml
可以运行XSLT 1.0脚本。并且因为XSLT脚本是 XML文件,所以您可以像任何XML一样从文件或字符串进行解析。不需要循环或条件if
逻辑。此外,您可以在其他语言(PHP,Java,C#等)中使用此XSLT脚本
XSLT (另存为.xsl文件,将在Python中引用)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- IDENTITY TRANSFROM: COPY DOC AS IS -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- REMOVE NAMESPACE PREFIXES, ADD DOC NAMESPACE -->
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="urn:ietf:params:xml:ns:epp-1.0">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
<强>的Python 强>
import lxml.etree as et
# LOAD XML AND XSL
doc = et.parse('Input.xml')
xsl = et.parse('XSLT_Script.xsl')
# CONFIGURE AND RUN TRANSFORMER
transform = et.XSLT(xsl)
result = transform(doc)
# OUTPUT RESULT TREE TO FILE
with open('Output.xml', 'wb') as f:
f.write(result)
<强>输出强>
<?xml version="1.0"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<check>
<check>
<id>ex61-irnic</id>
<id>ex999-irnic</id>
<authInfo>
<pw>1487441516170712</pw>
</authInfo>
</check>
</check>
<clTRID>TEST-12345</clTRID>
</command>
</epp>