xslt unescape两次(例如& amp;成为&)

时间:2010-08-16 21:52:35

标签: xslt twitter escaping twitter-feed

我正在尝试转换一些由Twitter Search api返回的xml。看起来内容元素包含两次转义的文本,即Inception样式。当我在我的XSL样式表中使用以下内容时,它只会忽略它一次:

<xsl:value-of select="atom:content" disable-output-escaping="yes" />

我如何进行第二轮失败?谢谢!

示例输入文档:

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns:google="http://base.google.com/ns/1.0" xml:lang="en-US" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.w3.org/2005/Atom" xmlns:twitter="http://api.twitter.com/">
  <id>tag:search.twitter.com,2005:search/from:myusername</id>
  <link type="text/html" href="http://search.twitter.com/search?q=from%3Amyusername" rel="alternate"/>
  <link type="application/atom+xml" href="http://search.twitter.com/search.atom?q=from%3Amyusername" rel="self"/>
  <title>from:myusername - Twitter Search</title>
  <link type="application/opensearchdescription+xml" href="http://search.twitter.com/opensearch.xml" rel="search"/>
  <link type="application/atom+xml" href="http://search.twitter.com/search.atom?q=from%3Amyusername&amp;since_id=21346924004" rel="refresh"/>
  <updated>2010-08-16T21:38:42Z</updated>
  <openSearch:itemsPerPage>15</openSearch:itemsPerPage>
  <entry>
    <id>tag:search.twitter.com,2005:21346924004</id>
    <published>2010-08-16T21:38:42Z</published>
    <link type="text/html" href="http://twitter.com/myusername/statuses/21346924004" rel="alternate"/>
    <title>testing special chars for a custom twitter client &lt; &gt; &amp; ' &#163; &#8364;</title>
    <content type="html">testing special chars for a custom twitter client &amp;lt; &amp;gt; &amp;amp; &amp;apos; &#163; &#8364;</content>
    <updated>2010-08-16T21:38:42Z</updated>
    <link type="image/png" href="http://a1.twimg.com/profile_images/820967365/twitter_avatar_normal.jpg" rel="image"/>
    <twitter:geo>
    </twitter:geo>
    <twitter:metadata>
      <twitter:result_type>recent</twitter:result_type>
    </twitter:metadata>
    <twitter:source>&lt;a href=&quot;http://twitter.com/&quot;&gt;web&lt;/a&gt;</twitter:source>
    <twitter:lang>en</twitter:lang>
    <author>
      <name>myusername</name>
      <uri>http://twitter.com/myusername</uri>
    </author>
  </entry>
</feed>

1 个答案:

答案 0 :(得分:1)

此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:char="character" xmlns:atom="http://www.w3.org/2005/Atom">
    <char:char ent="lt">&lt;</char:char>
    <char:char ent="gt">&gt;</char:char>
    <char:char ent="amp">&amp;</char:char>
    <char:char ent="apos">&apos;</char:char>
    <char:char ent="quot">&quot;</char:char>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="atom:content/text()" name="replace">
        <xsl:param name="pText" select="."/>
        <xsl:choose>
            <xsl:when test="contains($pText,'&amp;')">
                <xsl:variable name="vAfter" select="substring-after($pText,'&amp;')"/>
                <xsl:value-of select="concat(substring-before($pText,'&amp;'),
                                             document('')/*/char:*
                                             [@ent =
                                             substring-before($vAfter,';')])"
                                                       disable-output-escaping="yes"/>
                <xsl:call-template name="replace">
                    <xsl:with-param name="pText" select="substring-after($vAfter,';')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$pText"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

输出:

<feed xml:lang="en-US" xmlns:google="http://base.google.com/ns/1.0" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.w3.org/2005/Atom" xmlns:twitter="http://api.twitter.com/">
    <id>tag:search.twitter.com,2005:search/from:myusername</id>
    <link type="text/html" href="http://search.twitter.com/search?q=from%3Amyusername" rel="alternate"></link>
    <link type="application/atom+xml" href="http://search.twitter.com/search.atom?q=from%3Amyusername" rel="self"></link>
    <title>from:myusername - Twitter Search</title>
    <link type="application/opensearchdescription+xml" href="http://search.twitter.com/opensearch.xml" rel="search"></link>
    <link type="application/atom+xml" href="http://search.twitter.com/search.atom?q=from%3Amyusername&amp;since_id=21346924004" rel="refresh"></link>
    <updated>2010-08-16T21:38:42Z</updated>
    <openSearch:itemsPerPage>15</openSearch:itemsPerPage>
    <entry>
        <id>tag:search.twitter.com,2005:21346924004</id>
        <published>2010-08-16T21:38:42Z</published>
        <link type="text/html" href="http://twitter.com/myusername/statuses/21346924004" rel="alternate"></link>
        <title>testing special chars for a custom twitter client &lt; &gt; &amp; ' £ €</title>
        <content type="html">testing special chars for a custom twitter client < > & ' £ €</content>
        <updated>2010-08-16T21:38:42Z</updated>
        <link type="image/png" href="http://a1.twimg.com/profile_images/820967365/twitter_avatar_normal.jpg" rel="image"></link>
        <twitter:geo></twitter:geo>
        <twitter:metadata>
            <twitter:result_type>recent</twitter:result_type>
        </twitter:metadata>
        <twitter:source>&lt;a href="http://twitter.com/"&gt;web&lt;/a&gt;</twitter:source>
        <twitter:lang>en</twitter:lang>
        <author>
            <name>myusername</name>
            <uri>http://twitter.com/myusername</uri>
        </author>
    </entry>
</feed>

注意atom:content的文本节点现在是unescape,但结构不合理

编辑:如果您需要格式正确的输出,可以添加此输出声明:

<xsl:output cdata-section-elements="atom:content"/>

然后您可以删除disable-output-escaping="yes",因此您的输出将是:

<feed xml:lang="en-US" xmlns:google="http://base.google.com/ns/1.0" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns="http://www.w3.org/2005/Atom" xmlns:twitter="http://api.twitter.com/">
    <id>tag:search.twitter.com,2005:search/from:myusername</id>
    <link type="text/html" href="http://search.twitter.com/search?q=from%3Amyusername" rel="alternate"></link>
    <link type="application/atom+xml" href="http://search.twitter.com/search.atom?q=from%3Amyusername" rel="self"></link>
    <title>from:myusername - Twitter Search</title>
    <link type="application/opensearchdescription+xml" href="http://search.twitter.com/opensearch.xml" rel="search"></link>
    <link type="application/atom+xml" href="http://search.twitter.com/search.atom?q=from%3Amyusername&amp;since_id=21346924004" rel="refresh"></link>
    <updated>2010-08-16T21:38:42Z</updated>
    <openSearch:itemsPerPage>15</openSearch:itemsPerPage>
    <entry>
        <id>tag:search.twitter.com,2005:21346924004</id>
        <published>2010-08-16T21:38:42Z</published>
        <link type="text/html" href="http://twitter.com/myusername/statuses/21346924004" rel="alternate"></link>
        <title>testing special chars for a custom twitter client &lt; &gt; &amp; ' £ €</title>
        <content type="html"><![CDATA[testing special chars for a custom twitter client < > & ' £ €]]></content>
        <updated>2010-08-16T21:38:42Z</updated>
        <link type="image/png" href="http://a1.twimg.com/profile_images/820967365/twitter_avatar_normal.jpg" rel="image"></link>
        <twitter:geo></twitter:geo>
        <twitter:metadata>
            <twitter:result_type>recent</twitter:result_type>
        </twitter:metadata>
        <twitter:source>&lt;a href="http://twitter.com/"&gt;web&lt;/a&gt;</twitter:source>
        <twitter:lang>en</twitter:lang>
        <author>
            <name>myusername</name>
            <uri>http://twitter.com/myusername</uri>
        </author>
    </entry>
</feed>

注意:CDATA部分无法执行转义。