我试图编辑CDATA中的链接:
<paragraph>
<![CDATA[
<strong><a href="http://example.com/2014/12/08/article-title">Article Title</a></strong>Article Excerpt.
]]>
</paragraph>
目标是将段落更改为<p>
,同时在链接中添加其他标记。例如,所需的输出可以是:(并非所有<paragraph>
都有链接,有些只包含文本)
<p>
<strong><a href="http://example.com/2014/12/08/article-title?tacking_id=12345" style="font-size:1.1em; color:#067ab4; line-height:100%">Article Title</a></strong>Article Excerpt.
</p>
我尝试过以下代码,但它没有用。
<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>
答案 0 :(得分:4)
就XML处理器而言,paragraph
节点中的CDATA不包含链接,标记或单个文本节点以外的任何内容。它只是一串字符,所以如果你真的想改变它,你必须采用一些棘手的字符串操作。
您遇到的第一个问题是,在模板匹配&#34;段落#34;中,您不执行任何xsl:apply-templates
,因此您的第二个模板可以与{{{{}}下的文本节点匹配1}}永远不会被调用。
你的第一个模板应该是这样的
paragraph
现在,在与文本节点匹配的模板中,这是令人讨厌的地方,但你的主要问题是你做<xsl:template match="paragraph">
<p>
<xsl:apply-templates />
</p>
</xsl:template>
。但它是一个文本节点。单个文本节点。它没有可以匹配的子节点。
如果你真的,真的想让它以这种方式工作,模板看起来就像这样
<xsl:apply-templates select="child::node()"/>
这个答案可能说明为什么试图操纵CDATA是一个坏主意。
另一种不太令人不愉快的方法是进行两次XSLT转换。
第一个看起来像这样
<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>
标记变得微不足道了......
a
然后输出以下内容:
<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>
因此,如果您可以更改输入XML以消除CDATA,那么它将变得更加轻松......