【问题标题】:Parsing xml in bash在 bash 中解析 xml
【发布时间】:2016-03-21 11:59:11
【问题描述】:


我需要为特定内容解析给定的 XML 文件。不幸的是,我的系统上只有没有 xpath 的 xmllint(并且我不允许安装/更新任何其他来源)。 XML 将包含:

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Body>
    <CreateIncidentResponse xmlns="http://schemas.hp.com/SM/7" xmlns:cmn="http://schemas.hp.com/SM/7/Common" xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" message="Success" returnCode="0" schemaRevisionDate="2016-02-16" schemaRevisionLevel="2" status="SUCCESS" xsi:schemaLocation="http://schemas.hp.com/SM/7 /Incident.xsd">
      <model>
        <keys>
          <IncidentID type="String">IM0832268</IncidentID>
        </keys>
        <instance recordid="IM0832268 - Paul test 3 incident via soap" uniquequery="number=&quot;IM0832268&quot;">
          <IncidentID type="String">IM0832268</IncidentID>
          <Category type="String">request for change</Category>
          <OpenTime type="DateTime">2016-03-18T16:06:28+00:00</OpenTime>
          <OpenedBy type="String">Harlass, Alexander</OpenedBy>
          <Priority type="String">4</Priority>
          <Urgency type="String">medium</Urgency>
          <UpdatedTime type="DateTime">2016-03-18T16:06:28+00:00</UpdatedTime>
          <AssignmentGroup type="String">TS3-AOS</AssignmentGroup>
          <Description type="Array">
            <Description type="String">RH test incident description via soap row 1</Description>
            <Description type="String">RH test incident description via soap row 2</Description>
          </Description>
          <Contact type="String">Harlass, Rudolf</Contact>
          <Title type="String">Paul test 3 incident via soap</Title>
          <TicketOwner type="String">INTEGRATION.OVO</TicketOwner>
          <UpdatedBy type="String">INTEGRATION.OVO</UpdatedBy>
          <Status type="String">Open</Status>
          <Area type="String">it products</Area>
          <Subarea type="String">utilization</Subarea>
          <ProblemType type="String">request for change</ProblemType>
          <Impact type="String">low</Impact>
          <Service type="String">PI Automation and Orchestration Service</Service>
          <VIP type="Boolean">false</VIP>
          <TargetResolutionDate type="DateTime">2016-03-25T15:00:00+00:00</TargetResolutionDate>
          <SOD type="String">OML</SOD>
          <SourceId type="String">4711</SourceId>
          <UserIncident type="Boolean">false</UserIncident>
          <AlertId type="String">4712</AlertId>
          <MonitoredId type="String">MI4713</MonitoredId>
        </instance>
      </model>
      <messages>
        <cmn:message type="String">Audit Record successfully recorded and added.</cmn:message>
      </messages>
    </CreateIncidentResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

最后我需要这样的输出:

Create SUCCESS
Messages:
    Audit Record successfully recorded and added.
Incident ID: IM0832268
    Status: Open
    Severity: 4
    Brief Description: RH test incident description via soap row 1
    Opened by: integration.ovo
    Opened time: March 20, 2016 11:54:08 PM CET

我知道如何创建一个包含输出的字符串,但不幸的是我对 sed 或类似工具不太熟悉。
任何有关如何从 xml 中提取所需字符串的帮助将不胜感激。
提前致谢

【问题讨论】:

  • 你的系统上有xsltproc吗?
  • (如果您需要快速破解,请关注此评论。这不是一个长期解决方案。)即使您无法安装任何东西,您通常也可以编译并复制二进制文件(和依赖项)到那个系统,在您拥有写入权限的路径上。最坏的情况,/tmp 是可读写的。您可以尝试将新版本的xmllint 复制到该路径并从那里执行。
  • 也许awk.info/?doc/tools/xmlparse.html 可以提供帮助。不确定是否需要 gawk 或者您的系统是否有它,但大多数 gawk 特定代码都可以重写为普通 awk 而不会有太多麻烦。祝你好运。

标签: xml bash parsing


【解决方案1】:

大多数系统包含pythonperl 或其他具有实际XML 处理能力的语言。这将产生一个更好的解决方案,尝试从 bash 中的大量 XML 生成格式良好的报告。话虽如此,这里有一些使用 bash 提取这些数据的想法。

给定一个字符串,如:

<IncidentID type="String">IM0832268</IncidentID>

您可以像这样使用awk 获取值(假设您的数据在一个名为data.xml 的文件中):

awk -F'[<>]' '/IncidentID/ {print $3}' data.xml

Tje -F'[&lt;&gt;]'awk 字段分隔符设置为 &lt;&gt;,以便给定的行在字段中拆分如下:

| 1  |  2                     |  3      |  4        |  5 |
|    |IncidentID type="String"|IM0832268|/IncidentID|    |

上面的例子实际上会返回两行(因为你的数据中有两个 IncidentID 标签):

IM0832268
IM0832268

如果你知道这些总是一样的,你可以拿第一个:

awk -F'[<>]' '/IncidentID/ {print $3; exit}' data.xml

从如下行中提取属性:

<CreateIncidentResponse xmlns="http://schemas.hp.com/SM/7" xmlns:cmn="http://schemas.hp.com/SM/7/Common" xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" message="Success" returnCode="0" schemaRevisionDate="2016-02-16" schemaRevisionLevel="2" status="SUCCESS" xsi:schemaLocation="http://schemas.hp.com/SM/7 /Incident.xsd">

您可以先将其拆分为每个属性一行,如下所示:

grep '<CreateIncidentResponse' data.xml | tr ' ' '\n'

这会给你:

<CreateIncidentResponse
xmlns="http://schemas.hp.com/SM/7"
xmlns:cmn="http://schemas.hp.com/SM/7/Common"
xmlns:xmime="http://www.w3.org/2005/05/xmlmime"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
message="Success"
returnCode="0"
schemaRevisionDate="2016-02-16"
schemaRevisionLevel="2"
status="SUCCESS"
xsi:schemaLocation="http://schemas.hp.com/SM/7
/Incident.xsd">

然后您可以将其传递给awk 以提取属性值。为了 例如,获取message属性的值:

grep '<CreateIncidentResponse' data.xml | tr ' ' '\n' |
awk -F'"' '/message/ {print $2}'

这会产生:

Success

希望这足以让您入门。

【讨论】:

  • +1 表示第一段,但 -1 表示破坏了正确的第一段,并在您的答案的其余部分提出了脆弱的黑客攻击。
  • “脆弱的黑客”,我喜欢这样。我想我需要订购一件 T 恤。
  • :-) 我可以建议:“我的脆弱的 hack 比您的生产代码更强大。”
猜你喜欢
  • 2010-10-27
  • 2012-05-20
  • 2011-02-22
  • 1970-01-01
  • 2012-09-13
  • 1970-01-01
  • 2023-04-08
  • 2012-08-11
  • 1970-01-01
相关资源
最近更新 更多