Xml 无法处理cdata中的元素
我正在尝试编辑CDATA中的链接:Xml 无法处理cdata中的元素,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我正在尝试编辑CDATA中的链接: <paragraph> <![CDATA[ <strong><a href="http://example.com/2014/12/08/article-title">Article Title</a></strong>Article Excerpt. ]]> </paragraph> 文章节选。 ]]> 目标是将段落更改为,同时在链接
<paragraph>
<![CDATA[
<strong><a href="http://example.com/2014/12/08/article-title">Article Title</a></strong>Article Excerpt.
]]>
</paragraph>
文章节选。
]]>
目标是将段落更改为
,同时在链接中添加其他标记。例如,所需的输出可以是:(并非所有的
都有链接,有些只包含文本)
文章节选。
我尝试了下面的代码,但没有成功
<xsl:template match="paragraph">
<xsl:copy-of select="@*"/>
<xsl:text disable-output-escaping="yes"><![CDATA[<p>]]></xsl:text>
<xsl:value-of select="." disable-output-escaping="yes"/>
<xsl:text disable-output-escaping="yes"><![CDATA[</p>]]></xsl:text>
</xsl:template>
<xsl:template match="text()[contains(.,'<a href="') and contains(.,'">')]">
<xsl:variable name="link" select="substring-before(substring-after(., '<a href="'), '">')"/>
<xsl:text disable-output-escaping="yes"><![CDATA[<a href="]]></xsl:text>
<xsl:value-of disable-output-escaping="yes" select="$link"/>
<xsl:text disable-output-escaping="yes"><![CDATA[&tracking_id=12345" ]]></xsl:text>
<xsl:value-of select="$link_style"/>
<xsl:text disable-output-escaping="yes"><![CDATA[>]]></xsl:text>
<xsl:apply-templates select="child::node()"/>
<xsl:text disable-output-escaping="yes"><![CDATA[</a>]]></xsl:text>
</xsl:template>
]]>
]]>
]]>
]]>
就XML处理器而言,段落
节点中的CDATA不包含链接、标签或除单个文本节点以外的任何内容。它只是一个字符串,所以如果您真的想更改它,您必须求助于一些棘手的字符串操作
您遇到的第一个问题是,在匹配“段落”的模板中,您没有执行任何xsl:apply templates
,因此永远不会调用可以匹配段落下的文本节点的第二个模板
因此,第一个模板应该如下所示
<xsl:template match="paragraph">
<p>
<xsl:apply-templates />
</p>
</xsl:template>
<xsl:template match="text()[contains(.,'<a href="') and contains(.,'">')]">
<xsl:variable name="firstbit" select="substring-before(., '<a href="')"/>
<xsl:variable name="link" select="substring-before(substring-after(., '<a href="'), '">')"/>
<xsl:variable name="lastbit" select="substring-after(substring-after(., '<a href="'), '">')"/>
<xsl:value-of disable-output-escaping="yes" select="$firstbit"/>
<xsl:text disable-output-escaping="yes"><![CDATA[<a href="]]></xsl:text>
<xsl:value-of disable-output-escaping="yes" select="$link"/>
<xsl:text disable-output-escaping="yes"><![CDATA[?tracking_id=12345" ]]></xsl:text>
<xsl:value-of select="$link_style"/>
<xsl:text disable-output-escaping="yes"><![CDATA[>]]></xsl:text>
<xsl:value-of disable-output-escaping="yes" select="$lastbit"/>
</xsl:template>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="paragraph">
<p>
<xsl:value-of disable-output-escaping="yes" select="." />
</p>
</xsl:template>
</xsl:stylesheet>
然后输出以下内容:
<p>
<strong><a href="http://example.com/2014/12/08/article-title">Article Title</a></strong>Article Excerpt.
</p>
<p>
<strong><a href="http://example.com/2014/12/08/article-title?tracking_id=12345" style="color:#067ab4;">Article Title</a></strong>Article Excerpt.
</p>
文章节选。
因此,如果您可以更改输入XML以消除CDATA,那么它将变得非常简单……CDATA中没有任何元素—这就是它的用途!假设将SQL中的一行读入xml文件,其中一个字段包含HTML及其所有&wtf;实体、未终止的
标记和其他无效XML。你把它放在CData区域以防止XML试图解析它。嗨,蒂姆,非常感谢!我试试你的第一个解决办法。问题是我无法控制订阅源-我无法删除CDATA,因此必须找到令人讨厌的方法来处理它:(刚刚将您的解决方案应用到我的脚本中,效果非常好,非常感谢Tim!
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a">
<a href="{@href}?tracking_id=12345" style="color:#067ab4;">
<xsl:apply-templates />
</a>
</xsl:template>
</xsl:stylesheet>
<p>
<strong><a href="http://example.com/2014/12/08/article-title?tracking_id=12345" style="color:#067ab4;">Article Title</a></strong>Article Excerpt.
</p>