【问题标题】:In Perl using Mojo::DOM in XML mode, how do I match on contents of subtags?在 XML 模式下使用 Mojo::DOM 的 Perl 中,如何匹配子标签的内容?
【发布时间】:2017-02-09 20:37:45
【问题描述】:

我有以下 XML:

<Product>
  ...
    <TitleDetail>
      <TitleType>01</TitleType>
      <TitleElement>
        <TitleElementLevel>01</TitleElementLevel>
        <TitleText>This is the title I'm looking for</TitleText>
      </TitleElement>
    </TitleDetail>
  ...
</Product>

(如果你好奇的话,它是ONIX。)

我想提取标题,类型为 01。 我试过了:

say $dom->at('TitleDetail[TitleType="01"] > TitleElement > TitleText')

但这不起作用。看起来tag[attr=value] 语法实际上只适用于属性。

有没有一种简单的方法可以做我想做的事?

【问题讨论】:

  • 这是一个错误,是的,使用 / 而不是 ` > ` 作为标签分隔符...
  • TitleDetail[TitleType="01"] means "一个TitleDetail元素,其TitleType属性值正好等于01" 显然不正确。不幸的是,您不能使用对at 的单个调用,因为子查询是有限的检查属性,并且没有一个选择器提供检查节点文本的方法。

标签: xml perl dom mojolicious


【解决方案1】:

可以使用 Mojo::DOM 来完成,但它很长。有几次那里有 Mojo::Collections,所以你需要取出第一个元素。

use Mojo::DOM;

my $dom = Mojo::DOM->new->xml(1)->parse($xml);
say $dom->find("TitleType")->grep(sub{ $_->text eq "01"})->first
    ->following("TitleElement")->first->at("TitleText")->text;

【讨论】:

  • 谢谢!如果很快没有更好的情况出现,我会接受这个答案。但我不会使用它;在这种情况下,XML::XPath 变得更好。
  • @mscha 我同意 XML::XPath 更好。它看起来更干净,完成工作可能需要做的工作更少。
【解决方案2】:

也许我的问题是我用锤子插入螺丝...

我喜欢 Mojo::DOM 及其简单性,但也许它不太适合解析结构化 XML,我应该使用 XML::XPath:

my $xp = XML::XPath->new(xml=>$xml);
say $xp->findvalue('//TitleDetail[TitleType=01]/TitleElement/TitleText');

这可以满足我的需要。

【讨论】:

  • 现在只需切换到 XML::LibXML(或 XML::Twig),你就有了一个可以拧螺丝的电动工具——一旦你注意到你不坚持使用锤子 :)跨度>
  • @zdim 没有任何问题...Mojo::DOM 可以处理 HTML 和格式错误的 XML,而那些模块则不能。 :P
  • @ThisSuitIsBlackNot 对,谢谢,应该说“完美的螺丝”。另外,重点(XML::XPath)似乎只是为了XPath,所以也许我的评论完全没有意义。
  • @zdim,在这种情况下,我只有一条记录,我必须从中提取少量值,所以XML::XPath 就可以了。对于解析大型提要,XML::LibXMLXML::Twig 确实更好,我过去都使用过它们。但不喜欢它——必须处理每个标签名称中的命名空间等——这就是我首先查看Mojo::DOM 的原因。但是在这里,没有人会费心指定一个命名空间,所以我不必担心这一点。 ?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-17
  • 2015-06-25
  • 2015-08-18
  • 1970-01-01
  • 2016-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多