在 Perl 中解析 REST api XML 响应主体

Parsing REST api XML response body in Perl

我有两个问题:

1) 我正在尝试解析 GET 请求的响应,add/delete 一个节点并使用 PUT 将其发回。正在使用 XML::LibXML,用于执行此类操作的正确方法。我担心的是,在我用 XML::LibXML 处理后,PUT 会期望内容吗?我尝试使用 XML::Simple 但它没有用。

2) 我正在尝试使用 XML::LibXML 从我从 GET 请求收到的 REST API 响应正文中解析 XML。它找不到任何东西。它在第 16 行失败说 "invalid expression at /" 这是代码。

  1  my $disk_name = "Hard disk 2";
  2  my $parser = XML::LibXML->new();
  3  my $query;
  4  my $name="";
  5  
  6    my $doc    = $parser->parse_string ($data_xml); 
  7    my $xpc = XML::LibXML::XPathContext->new($doc);
  8    $xpc->registerNs('x', 'http://www.vmware.com/vcloud/v1.5');
  9    $xpc->registerNs('y', 'http://schemas.dmtf..');
  10    $xpc->registerNs('z','http://www.vmware.com/vcloud/v1.5');
  11    
  12    log("loop thr the nodes");
  13    log($doc);
  14    foreach my $item ($xpc->findnodes('/x:RasdItemsList/x:Item')) {
  15    log("found a match thr libXML");
  16      $name = $item->findnodes("/y:rasd:ElementName[text()='$disk_name']"); 
  17      if($name ne '') {
  18          log("The name of the node is " . $name->to_literal);
  19          $name->setData('New disk');
  20      }
  21    }

这是 $data_xml 的样子:

 <RasdItemsList xmlns="="http://www.vmware.com/vcloud/v1.5" xmlns:rasd="http://schemas....." xmlns:xsi=.......some more text>
          <Link rel="edit" type="some text"/>
          <Item>
              <rasd:Address>0</rasd:Address>
              <rasd:Description>SCSI Controller</rasd:Description>
              <rasd:ElementName>SCSI Controller 0</rasd:ElementName>
              <rasd:InstanceID>2</rasd:InstanceID>
              <rasd:ResourceSubType>lsilogic</rasd:ResourceSubType>
              <rasd:ResourceType>6</rasd:ResourceType>
          </Item>
          <Item>
              <rasd:AddressOnParent>0</rasd:AddressOnParent>
              <rasd:Description>Hard disk</rasd:Description>
              <rasd:ElementName>Hard disk 1</rasd:ElementName>
              <rasd:HostResource xmlns:ns12="txt" ns12:capacity="59392" ns12:busSubType="lsilogic" ns12:busType="6"></rasd:HostResource>
              <rasd:InstanceID>2000</rasd:InstanceID>
              <rasd:Parent>2</rasd:Parent>
              <rasd:ResourceType>17</rasd:ResourceType>
          </Item>
       ...... some more <Items>
      </RasdItemsList>

我收到了 GET 请求的响应。我将它除以 \n 并将其放入 $data_xml。所以上面的所有行都被附加到一个巨大的字符串 $data_xml 中。

在此先感谢您的帮助。

My concern is would PUT expect the content after I process it with XML::LibXML?

我不知道有问题的 API 是否接受包含 XML 内容的 PUT。为此,您需要查阅 API 文档。

XML::LibXML 确实是完成这项工作的完美工具,但无论您使用什么工具,您都需要了解自己所拥有的 XML 方法。

你只问了一个问题。您是否还想问为什么 XML::LibXML 找不到任何节点?

如果是,原因可能是 xmlns="http://www........ some text" 你太害羞了。这不是任何旧属性,它是一个 XML namespace,文档中可能至少还有一个定义 rasd: 前缀的属性。

除非您设置了 XPath context,否则您的查询 $doc->findnodes('RasdItemsList/Item') 只会查找没有命名空间的元素。一个简单的解决方法是编写: $doc->findnodes('*[local-name()="RasdItemsList"]/*[local-name()="Item"]') - 这将测试名称而不考虑命名空间。但是,如果您要添加新节点,则需要实际的命名空间。