免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5684 | 回复: 3
打印 上一主题 下一主题

Shell 处理XML的问题(节点丢失) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-06 22:30 |只看该作者 |倒序浏览
近来需要使用shell来处理XML文件。
1. 通过shell脚本解析XML,获取节点名称和节点值
2. 通过shell脚本动态生成XML。
拿到XXX部门发来得XML文件模板test.xml:
<?xml version="1.0" encoding="UTF-8"?>

<RA>
        <SvcCont>
                <![CDATA[
                        <DataConsistencyReq>
                                <DataType>111</DataType>
                                <ConsistencyType>1</ConsistencyType>
                                <ValidTimeStart>20111101000000</ValidTimeStart>
                                <ValidTimeEnd>20111130235959</ValidTimeEnd>
                                <UserRange>10086</UserRange>
                                <UserRange>1355004</UserRange>
                                <UserRange></UserRange>
                                <SPRange></SPRange>
                        </DataConsistencyReq>                             
                ]]>
        </SvcCont>
</RA>

XML文件中节点说明:
DataType                 必须且只能填1项
ConsistencyType     必须且只能填1项
ValidTimeStart         可以没有
ValidTimeEnd           必须且只能填1项
UserRange               可以没有,也可以有多项
SPRange                  可以没有,也可以有多项

Shell脚本 taglist.sh:
#! /bin/sh -
cat "$1" |
  sed -e 's#systemitem *role="url"#URL#g' -e 's#/systemitem#URL#' |
    tr ' (){}[]' '\n\n\n\n\n\n\n' |
          egrep '>[^<>]+</' |
            awk -F'[<>]' -v FILE="$1" \
                    '{ print($2, $3) }'

# sh taglist.sh test.xml
DataType 111
ConsistencyType 1
ValidTimeStart 20111101000000
ValidTimeEnd 20111130235959
UserRange 10086
UserRange 1355004

通过执行Shell可以得出如上结果,但跟我的需求结果有些差异,我预想输出的应该是:
DataType 111
ConsistencyType 1
ValidTimeStart 20111101000000
ValidTimeEnd 20111130235959
UserRange 10086
UserRange 1355004
UserRange                                   <-   这个UserRange 因为节点没有值,这里应该是空值
SPRange                                      <-   这个SPRange 因为节点没有值,这里应该是空值
-------------------------------------------------------
请各位帮忙修改我的shell以达到我的预想输出结果。谢谢!

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:51:162015年亚洲杯之阿曼
日期:2015-04-07 20:00:59
2 [报告]
发表于 2011-12-06 22:52 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
3 [报告]
发表于 2011-12-06 22:56 |只看该作者

论坛徽章:
0
4 [报告]
发表于 2011-12-06 23:28 |只看该作者
问题已经解决,
感谢楽楽提供的awk单行脚本:
awk 'BEGIN{FS="[<>]"}NR>6 && NR<15{sub(/\t+/,"",$1);print $2,$3}' test.xml
脚本说明:
NR>6 && NR<15 几行与几行 之间(虽然这里写的比较死板。但是不影响使用,可以考虑自动匹配)
BEGIN{FS="[<>]"} 定义多分隔符
sub(/\t+/,"",$1) 把 $1 的 多 \t 替换为 一个 “”
再打印出 $2 $3

感谢小玉提供的sed单行脚本:
sed -n -r 's/^[\t ]*<([^>]+)>([^<>]*)<\/\1>/\1=\2/p' test.xml
脚本说明:
-n 只显示被特殊处理的行,同 /p 配合使用
-r  支持sed 延伸型正规表示法的语法
's/^[\t ]*<([^>]+)>([^<>]*)<\/\1>/\1=\2/p' 这段 s/  /p 之间没看懂。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP