忘记密码   免费注册 查看新帖 | 论坛精华区

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT HPC论坛 徽章 文库 沙龙 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
12
最近访问板块 发新帖
楼主: capfsxl

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

论坛徽章:
0
发表于 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
发表于 2013-09-28 16:13 |显示全部楼层
回复 10# 104359176

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

论坛徽章:
0
发表于 2013-09-28 16:36 |显示全部楼层
回复 11# iamlimeng

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

论坛徽章:
0
发表于 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
发表于 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
发表于 2013-10-02 11:50 |显示全部楼层
我晕 怎么跑这里来呃了

论坛徽章:
0
发表于 2013-10-02 13:21 |显示全部楼层
已采用14楼的优化方案,感谢各位的热情帮助!

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


   

论坛徽章:
0
发表于 2017-09-12 13:47 |显示全部楼层
本帖最后由 本友会机友会摄友会 于 2017-09-14 11:54 编辑
  1. $输入文件名 = "a:\pscode\0\xml\2017-09-12.xml"
  2. $所有device = (select-xml -Path $输入文件名 -XPath "/function/device").node #xpath路径区分大小写。不判断device标签的个数,只获取所有device
  3. foreach  ($单个device in $所有device)
  4. {
  5.         Write-Host '--------【device开始】--------'
  6.         "device_name {0}" -f $单个device.device_name
  7.         "interface_name {0}" -f $单个device.interface_name
  8.         "commited_information_rate {0}" -f $单个device.commited_information_rate
  9.         
  10.         $所有host = $单个device.host
  11.         foreach  ($单个host in $所有host)
  12.         {
  13.                 "ip {0}" -f $单个host.ip
  14.                 "mask {0}" -f $单个host.mask
  15.         }
  16.         Write-Host '--------【device结束】--------'
  17. }
复制代码


实际代码就5行。

win,linux通用,只需要把输入文件名,改成linux格式,如/home/aaa/bbb.xml。
win7+powershell 5.1 运行此代码通过。


返回:
--------【device开始】--------
device_name 202.197.12.199
interface_name gei-0/2
commited_information_rate 5000
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
--------【device结束】--------
--------【device开始】--------
device_name 202.197.12.200
interface_name gei-0/1
commited_information_rate 10000
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
--------【device结束】--------
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10张SACC2017门票等你来拿~

在数字化转型时代,云已成为万物智能的数字化大脑。而随着大数据应用、人工智能、移动互联网等技术的飞速发展,“智慧 +” 的概念正在深入到各行各业,提升企业效率,释放商业潜能,创造全新机遇。作为国内顶级技术盛会之一,2017 中国系统架构师大会(SACC2017)将于 10 月 19-21 日在北京新云南皇冠假日酒店震撼来袭。今年,大会以 “云智未来” 为主题,云集国内外顶级专家,围绕云计算、人工智能、大数据、移动互联网、产业应用等热点领域展开技术探讨与交流。本届大会共设置 2 大主会场,18 个技术专场;邀请来自互联网、金融、制造业、电商等多个领域,100 余位技术专家及行业领袖来分享他们的经验;并将吸引 4000 + 人次的系统运维、架构师及 IT 决策人士参会,为他们提供最具价值的交流平台。
----------------------------------------
优惠时间:2017年10月19日前

活动链接>>
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP