从 XML 中的 cdata 文本中提取 img src

Extract img src from cdata text in XML

我想从 XML 文件中提取 img src 值。

测试输入:

<ROOT>
   <ITEM>
      <DESCRIPTION><![CDATA[<p align="left" dir="ltr">
    <span lang="EN">lorem ipsum</span></p>
<p>
    some text</p>
<p>
    <img alt="" src="https://example.com/hello.jpg" /></p>
]]></DESCRIPTION>
    </ITEM>
</ROOT>         

最好的方法是什么?使用 XSLT 或 XML 解析器,如 xmllint?

目前我正在尝试使用 xmllint:

xmllint --xpath '//ROOT/ITEM/DESCRIPTION/text()' input.xml | egrep -o 'src=".*(\.png|\.jpg)'

...但输出如下:

src="https://example.com/hello.jpg

我当然可以使用 sed 等工具删除 src=",但也许有更好更干净的解决方案来提取链接?

您需要使用 XPath 3 或 XSLT 3 深入挖掘 parse-xml-fragment:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">    

  <xsl:output method="text" indent="yes" html-version="5"/>

  <xsl:template match="/">
     <xsl:value-of select="ROOT/ITEM/DESCRIPTION/parse-xml-fragment(.)//img/@src"/>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/3NSSEv7

Saxon 9.9 HE 在 .NET 中可用,Java 和 C/C++/Python 版本到 run/use XSLT 3。

如果 CDATA 包含 HTML 格式不正确的 X(HT)ML,那么您可以使用由 David Carlisle 在 XSLT 2 (https://github.com/davidcarlisle/web-xslt/blob/master/htmlparse/htmlparse.xsl) 中实现的 HTML 解析器:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:html-parser="data:,dpc"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:import href="https://github.com/davidcarlisle/web-xslt/raw/master/htmlparse/htmlparse.xsl"/>

  <xsl:output method="text"/>

  <xsl:template match="/">
     <xsl:value-of select="ROOT/ITEM/DESCRIPTION/html-parser:htmlparse(., '', true())//img/@src"/>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/3NSSEv7/1

如果您的 CDATA 部分格式正确 XML 如果它不在 CDATA 部分中,您可以将 xmllint 的输出通过管道传输到 xmllint,以便 CDATA 被解析为 XML。

在您的特定示例中,您必须将输出包装在另一个元素中(例如 x)以使其格式正确。

示例...

xmllint --xpath 'concat("<x>",string(//ROOT/ITEM/DESCRIPTION),"</x>")' input.xml | xmllint --xpath 'string(//img/@src)' -

输出...

https://example.com/hello.jpg