Xslt 从XML格式的cdata文本中提取img src
我想从XML文件中提取img src值 测试输入:Xslt 从XML格式的cdata文本中提取img src,xslt,xml-parsing,xmllint,Xslt,Xml Parsing,Xmllint,我想从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="" s
<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>
…但输出类似于:
src="https://example.com/hello.jpg
当然,我可以用sed之类的工具删除
src=“
,但也许有更好更干净的解决方案来提取链接?您需要深入挖掘XPath 3或XSLT 3中的解析xml片段
:
<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>
Saxon 9.9可以在.NET、Java和C/C++/Python版本中运行/使用XSLT 3
如果CDATA包含的HTML不是格式良好的X(HT)ML,那么可以使用David Carlisle在XSLT 2中()实现的HTML解析器:
您需要深入挖掘XPath 3或XSLT 3中的
解析xml片段
:
<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>
Saxon 9.9可以在.NET、Java和C/C++/Python版本中运行/使用XSLT 3
如果CDATA包含的HTML不是格式良好的X(HT)ML,那么可以使用David Carlisle在XSLT 2中()实现的HTML解析器:
如果您的CDATA节不是在CDATA节中,那么它将是格式良好的XML,那么您可以通过管道将xmllint的输出传输到xmllint,从而将CDATA解析为XML 在您的特定示例中,您必须将输出包装到另一个元素中(示例中为
x
),以使其格式良好
例如
xmllint --xpath 'concat("<x>",string(//ROOT/ITEM/DESCRIPTION),"</x>")' input.xml | xmllint --xpath 'string(//img/@src)' -
如果您的CDATA节不是在CDATA节中,那么它将是格式良好的XML,那么您可以通过管道将xmllint的输出传输到xmllint,以便将CDATA解析为XML 在您的特定示例中,您必须将输出包装到另一个元素中(示例中为
x
),以使其格式良好
例如
xmllint --xpath 'concat("<x>",string(//ROOT/ITEM/DESCRIPTION),"</x>")' input.xml | xmllint --xpath 'string(//img/@src)' -
如果我在示例XML上运行这个XSLT,它会工作,但是如果我在实际XML上运行它,我会得到错误:
在stage-2第11行第88列的xsl:value of/@select的char 46处出错。XSLT:FODC0006:parse-XML-fragment()的第一个参数不是格式正确且命名空间格式正确的XML片段。XML解析器报告:org.XML.sax.SAXParseException;systemId:file:./stage-2.xslt;行号:2;
列号:176;引用了实体“ndash”,但未声明。parse-XML-fragment()的第一个参数不是格式正确且命名空间格式正确的XML片段。XML解析器报告:org.XML.sax.SAXParseException;systemId:file:./stage-2.xslt;行号:2;列号:176;实体“ndash”“已被引用,但未声明。
奇怪,我正在运行来自Saxonica的Saxon HE 9.8.0.8J。输入XML没有问题,至少如果我在浏览器中打开它,我不会得到任何错误,我们无法针对您在问题中未显示的输入编写代码,但错误消息清楚地表明,我尝试使用parse xml fragment
解析的CDATA节内容不是格式良好的片段,因为它似乎引用了一个类似ndash
的实体,HTML解析器知道该实体,但除非有DTD,否则xml解析器不知道。因此,parse xml fragment
无法解析该内容,您可能需要一个HTML解析器将CDATA部分内容提供给,Saxon PE和EE对此有扩展,他没有。您可以使用David Carlisle在纯XSLT 2中完成的HTML解析器。有一个带有实体引用的示例,HTML解析器似乎可以很好地解析该实体引用。如果我在示例XML上运行此XSLT,它会工作,但如果我在实际XML上运行它,我会得到错误:错误,位于stage-2第11行第88列的xsl:value of/@select的char 46处。XSLT:FODC0006:parse-XML-fragment()的第一个参数不是格式良好且命名空间格式良好的XML片段。XML解析器报告:org.XML.sax.SAXParseException;systemId:file:./stage-2.xslt;行号:2代码>列号:176;实体“ndash”已被引用,但未声明。parse-xml-fragment()的第一个参数不是格式良好且命名空间格式良好的xml片段。XML解析器报告:org.XML.sax.SAXParseException;systemId:file:./stage-2.xslt;行号:2;栏目号:176;实体“ndash”已被引用,但未声明。
奇怪,我正在运行来自Saxonica的Saxon HE 9.8.0.8J。输入XML没有问题,至少如果我在浏览器中打开它,我不会得到任何错误,我们无法针对您在问题中未显示的输入编写代码,但错误消息清楚地表明,我尝试使用parse xml fragment
解析的CDATA节内容不是格式良好的片段,因为它似乎引用了一个类似ndash
的实体,HTML解析器知道该实体,但除非有DTD,否则xml解析器不知道。因此,parse xml fragment
无法解析该内容,您可能需要一个HTML解析器将CDATA部分内容提供给,Saxon PE和EE对此有扩展,他没有。您可以使用David Carlisle在纯XSLT 2中完成的HTML解析器。有一个例子,其中有一个实体引用,HTML解析器似乎解析得很好。@BélaNem-Yes如果有多个img
元素,它将只输出第一个元素的src值(因为xmllint使用xpath 1.0)。您可能会切换到xmlstarlet并迭代每个img
。如果稍后有时间,我将添加一个示例。@BélaNem-Yes如果有多个img
元素,它将只输出第一个元素的src值(因为xmllint使用xpath 1.0)。您可能会切换到xmlstarlet并迭代每个img
。如果我稍后有时间,我将添加一个示例。
https://example.com/hello.jpg