免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: capfsxl
打印 上一主题 下一主题

优化有酬劳,如何读取XML同名标签个数不确定里的内容? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2013-09-28 13:38 |只看该作者
本帖最后由 iamlimeng 于 2013-09-28 13:46 编辑
  1. #!/usr/bin/perl
  2. use strict;
  3. use XML::Simple qw(XMLin);
  4. my $device_num = $ARGV[0];
  5. my @lines = <DATA>;
  6. my $text = join '', @lines;
  7. my $xml_data = XMLin($text);
  8. my $device_list  = $xml_data->{device};
  9. my $device_times = ref ($device_list) eq ref ([]) ? scalar(@$device_list) : 1;

  10. if ($device_num > $device_times) { print "Out of device scope, supply right device num pls!\n"; }
  11. else {
  12. my $device_name = ($device_times == 1)?$device_list->{device_name}:$xml_data->{device}[$device_num-1]->{device_name};
  13. my $config = <<END;
  14. system-view
  15. ip router $device_name
  16. undo shutdown
  17. return
  18. END
  19. print $config;
  20. }
  21. <>;

  22. __DATA__
  23. <function funcname="gray_list" mode="predefined" no="no">
  24.   <task_name>20130506113902_989513309</task_name>
  25.   <device>
  26.     <device_name>202.197.12.199</device_name>
  27.     <interface_name>gei-0/2</interface_name>
  28.     <commited_information_rate>5000</commited_information_rate>
  29.     <host>
  30.       <ip>192.168.1.1</ip>
  31.       <mask>255.255.255.0</mask>
  32.     </host>
  33.   </device>
  34.   <device>
  35.     <device_name>202.197.12.200</device_name>
  36.     <interface_name>gei-0/2</interface_name>
  37.     <commited_information_rate>5000</commited_information_rate>
  38.     <host>
  39.       <ip>192.168.1.1</ip>
  40.       <mask>255.255.255.0</mask>
  41.     </host>
  42.   </device>
  43. </function>
复制代码
楼主想要的可能是这个,把话费给我吧!

论坛徽章:
0
12 [报告]
发表于 2013-09-28 16:13 |只看该作者
回复 10# 104359176

感谢您的及时回复,我的这个问题必须要判断吗?有没有一种不用判断的通式?因为一旦有判断,深度越深,就越繁琐,三级深度,就有8种情况,我想简化的就是不进行判断!
   

论坛徽章:
0
13 [报告]
发表于 2013-09-28 16:36 |只看该作者
回复 11# iamlimeng

感谢您的详细解答,你的方法我之前也用过,单从这个例子来讲,这样的方法是简化了,少写一个$config,但我要从XML文档读取的东西非常多,END与END之间的东西并不多,最大的问题是再增加深度,判断的次数级数次增长,比如我还取不确定几个<host>里面的内容,最想优化的就是不进行判断,能否?能消息于我你的微信吗?
   

论坛徽章:
0
14 [报告]
发表于 2013-09-28 18:22 |只看该作者
回复 13# capfsxl

我隐隐约约明白了你的意思,你应该希望提取出来的数据都是数组,这样就不用判断某个键下是一个元素,还是多个,下面是例程,希望能帮到你。但你同样面临输入的device_num超出数据范围的问题,这个还是要加判断的。
  1. #!/usr/bin/perl

  2. use strict;
  3. use XML::Simple qw(XMLin);
  4. my $device_num = $ARGV[0];
  5. my @lines = <DATA>;
  6. my $text = join '', @lines;
  7. my $xml_data = XMLin($text,ForceArray =>1);

  8. my $device_name = $xml_data->{device}[$device_num-1]->{device_name}[0];
  9. my $config = <<END;
  10. system-view
  11. ip router $device_name
  12. undo shutdown
  13. return
  14. END
  15. print $config;
  16. <>;

  17. __DATA__
  18. <function funcname="gray_list" mode="predefined" no="no">
  19.   <task_name>20130506113902_989513309</task_name>
  20.   <device>
  21.     <device_name>202.197.12.199</device_name>
  22.     <interface_name>gei-0/2</interface_name>
  23.     <commited_information_rate>5000</commited_information_rate>
  24.     <host>
  25.       <ip>192.168.1.1</ip>
  26.       <mask>255.255.255.0</mask>
  27.     </host>
  28.   </device>
  29.   <device>
  30.     <device_name>202.197.12.200</device_name>
  31.     <interface_name>gei-0/2</interface_name>
  32.     <commited_information_rate>5000</commited_information_rate>
  33.     <host>
  34.       <ip>192.168.1.1</ip>
  35.       <mask>255.255.255.0</mask>
  36.     </host>
  37.   </device>
  38. </function>
复制代码

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
15 [报告]
发表于 2013-09-28 19:06 |只看该作者
回复 12# capfsxl


    必须要判断,但要用递归,注意我的代码,和深度无关,其实这个问题有一个另类的解决办法。就是将 YAML 的格式进行处理:




C:\Documents and Settings\Administrator\桌面>cmd
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\Administrator\桌面>perl Parse-xml.pl
---
device:
  - commited_information_rate: 5000
    device_name: 202.197.12.199
    host:
      - ip: 192.168.1.1
        mask: 255.255.255.0
      - ip: 192.168.45.115
        mask: 255.255.255.0
      - ip: 192.168.54.112
        mask: 255.255.255.0
    interface_name: gei-0/2
  - commited_information_rate: 10000
    device_name: 202.197.12.200
    host:
      - ip: 172.168.2.1
        mask: 255.255.255.0
      - ip: 172.168.2.15
        mask: 255.255.255.0
      - ip: 172.168.5.12
        mask: 255.255.255.0
    interface_name: gei-0/1
funcname: gray_list
mode: predefined
no: no
task_name: 20130506113902_989513309

Tag:< device> occur 2 times
Tag:<device ->  host> occur 3 times
Tag:<device ->  host> occur 3 times

C:\Documents and Settings\Administrator\桌面>

论坛徽章:
0
16 [报告]
发表于 2013-10-02 11:50 |只看该作者
我晕 怎么跑这里来呃了

论坛徽章:
0
17 [报告]
发表于 2013-10-02 13:21 |只看该作者
已采用14楼的优化方案,感谢各位的热情帮助!

论坛徽章:
0
18 [报告]
发表于 2013-10-02 16:58 |只看该作者
回复 1# capfsxl
你应该多了解一下perl的数据结构, 包括array和hash的引用,以及复杂数据结构的构造。
再读一下 XML::Simple 的文档资料 perldoc XML::Simple.
资料例子中的Tag <server 。。> 和你的<device>相吻合。


   

论坛徽章:
0
19 [报告]
发表于 2017-09-12 13:47 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP