2017-08-22 17 views
0

我有這樣一個xml:如何從Python中的XML中刪除ns?

<?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刪除納秒。 但它沒有奏效。 你能幫我達成我的目標嗎?

+0

只要做一個簡單的查找和替換/刪除字符串的'ns1:'或'ns0:' – AK47

+1

...當然如果字符串「ns1:」被包含在某個地方而不是命名空間符。 – larsks

回答

1

這是Remove namespace and prefix from xml in python using lxml(顯示如何修改元素的名稱空間)和lxml: add namespace to input file(顯示如何重置頂部名稱空間映射)的組合。

的代碼是一個小哈克(我特別懷疑它是否是猶太使用_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> 
0

考慮XSLT,專爲轉換XML文件,如刪除命名空間的專用語言。 Python的第三方模塊lxml可以運行XSLT 1.0腳本。由於XSLT腳本 XML文件,因此可以像解析XML一樣從文件或字符串中解析。無需循環或條件if邏輯。此外,還可以使用其他語言(PHP,Java和C#等)

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> 

這個XSLT腳本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>