【问题标题】:Generating XML dynamically in Python在 Python 中动态生成 XML
【发布时间】:2012-05-28 05:31:41
【问题描述】:

各位朋友,我正在使用 Python 库生成 XML 数据,如下所示

def multiwan_info_save(request):
    data = {}
    init = "init"
    try:
       form = Addmultiwanform(request.POST)
    except:
        pass
    if form.is_valid():
        from_sv = form.save(commit=False)
        obj_get = False
        try:
            obj_get = MultiWAN.objects.get(isp_name=from_sv.isp_name)
        except:
            obj_get = False
            nameservr  = request.POST.getlist('nameserver_mw') 
            for nm in nameservr:
                nameserver1, is_new = NameServer.objects.get_or_create(name=nm)
                from_sv.nameserver = nameserver1
                from_sv.save()
        #    main(init)    
        top = Element('ispinfo')
       # comment = Comment('Generated for PyMOTW')
        #top.append(comment)
        all_connection = MultiWAN.objects.all()
        for conn in all_connection:
            child = SubElement(top, 'connection number ='+str(conn.id)+'name='+conn.isp_name+'desc='+conn.description )
            subchild_ip = SubElement(child,'ip_address')
            subchild_subnt = SubElement(child,'subnet')
            subchild_gtwy = SubElement(child,'gateway')
            subchild_nm1 = SubElement(child,'probe_server1')
            subchild_nm2 = SubElement(child,'probe_server2')
            subchild_interface = SubElement(child,'interface')
            subchild_weight = SubElement(child,'weight')
            subchild_ip.text = str(conn.ip_address)
            subchild_subnt.text = str(conn.subnet)
            subchild_gtwy.text = str(conn.gateway)
            subchild_nm1.text = str(conn.nameserver.name)
           # subchild_nm2.text = conn.
            subchild_weight.text = str(conn.weight)
            subchild_interface.text = str(conn.interface)
        print "trying to print _____________________________"
        print tostring(top)   
        print "let seeeeeeeeeeeeeeeeee +++++++++++++++++++++++++"

但我得到的输出如下所示

<ispinfo><connection number =5name=Airtelllldesc=Largets TRelecome ><ip_address>192.168.1.23</ip_address><subnet>192.168.1.23</subnet><gateway>192.168.1.23</gateway><probe_server1>192.168.99.1</probe_server1><probe_server2 /><interface>eth0</interface><weight>160</weight></connection number =5name=Airtelllldesc=Largets TRelecome ><connection number =6name=Uninordesc=Uninor><ip_address>192.166.55.23</ip_address><subnet>192.166.55.23</subnet><gateway>192.168.1.23</gateway><probe_server1>192.168.99.1</probe_server1><probe_server2 /><interface>eth0</interface><weight>160</weight></connection number =6name=Uninordesc=Uninor><connection number =7name=Airteldesc=Largets TRelecome ><ip_address>192.168.1.23</ip_address><subnet>192.168.1.23</subnet><gateway>192.168.1.23</gateway><probe_server1>192.168.99.1</probe_server1><probe_server2 /><interface>eth0</interface><weight>160</weight></connection number =7name=Airteldesc=Largets TRelecome ></ispinfo>

我只想知道如何以正确的 XML 格式编写此 XML?

提前致谢

【问题讨论】:

  • 不要尝试使用connection number =作为标签名...
  • 哦,但我的问题是如何以正确的 xml 格式编写结果而不是获得单行结果?

标签: python xml xml-serialization xml-parsing


【解决方案1】:

更新包括模拟 XML 树的创建和打印

基本问题

您的代码正在生成无效的连接标签,如下所示:

<connection number =5name=Airtelllldesc=Largets TRelecome ></connection number =5name=Airteldesc=Largets TRelecome >

当它们看起来像这样时(我省略了中间的子元素。您的代码正在正确生成这些):

<connection number="5" name="Airtellll" desc="Largets TRelecome" ></connection>

如果你有有效的 XML,这段代码会整齐地打印出来:

from lxml import etree
xml = '''<ispinfo><connection number="5" name="Airtellll" desc="Largets TRelecome" ><ip_address>192.168.1.23</ip_address><subnet>192.168.1.23</subnet><gateway>192.168.1.23</gateway><probe_server1>192.168.99.1</probe_server1><probe_server2 /><interface>eth0</interface><weight>160</weight></connection></ispinfo>'''
xml = etree.XML(xml)
print etree.tostring(xml, pretty_print = True)

生成有效的 XML

下面是一个小模拟:

from lxml import etree

# Some dummy text
conn_id = 5
conn_name = "Airtelll"
conn_desc = "Largets TRelecome"
ip = "192.168.1.23"

# Building the XML tree
# Note how attributes and text are added, using the Element methods
# and not by concatenating strings as in your question
root = etree.Element("ispinfo")
child = etree.SubElement(root, 'connection',
                 number = str(conn_id),
                 name = conn_name,
                 desc = conn_desc)
subchild_ip = etree.SubElement(child, 'ip_address')
subchild_ip.text = ip

# and pretty-printing it
print etree.tostring(root, pretty_print=True)

这将产生:

<ispinfo>
  <connection desc="Largets TRelecome" number="5" name="Airtelll">
    <ip_address>192.168.1.23</ip_address>
  </connection>
</ispinfo>

【讨论】:

  • Python 2.7.3——我应该在回答中这么说,抱歉。 :)
【解决方案2】:

单行是正确的,在某种意义上,XML 解析器会理解它。

对于sys.stdout 的漂亮打印,请使用Elementdump 方法。

对于流的漂亮打印,请使用ElementTreewrite 方法。

【讨论】:

  • 是的,没关系,但我想提高程序的可读性..?
  • @user1409289:你试过dump吗?
猜你喜欢
  • 1970-01-01
  • 2013-01-07
  • 2014-07-16
  • 2013-04-27
  • 1970-01-01
  • 1970-01-01
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多