XSL:如何防止xsltproc篡改属性值中的转义HTML字符串?

时间:2014-11-13 21:33:10

标签: xml csv xslt

我正在读取一个扁平实体的XML文件,其中的值都在属性中,并尝试生成分隔的文本文件(CSV,但管道不是逗号 1 )。问题在于,其中一个属性具有HTML的任意blob作为值,其中(在XML文件中)已正确转义。但是,当我使用我的样式表运行xsltproc时,我正在获取HTML,完成换行符,这意味着我的输出不再是每个元素一行。

示例XML输入 - 这是源代码中的一行,但我在此处插入了人工换行符以便于阅读:

<row Id="-1" Reputation="1" CreationDate="2010-11-18T19:05:26.543" DisplayName="Community" 
  LastAccessDate="2010-11-18T19:05:26.543" Location="on the server farm" 
  AboutMe="&lt;p&gt;Hi, I'm not really a person.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I'm a background process that helps keep this site clean!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I do things like&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Randomly poke old unanswered questions every hour so they get some attention&lt;/li&gt;&#xA;&lt;li&gt;Own community questions and answers so nobody gets unnecessary reputation from them&lt;/li&gt;&#xA;&lt;li&gt;Own downvotes on spam/evil posts that get permanently deleted&lt;/li&gt;&#xA;&lt;li&gt;Own suggested edits from anonymous users&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&quot;http://meta.stackexchange.com/a/92006&quot;&gt;Remove abandoned questions&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;" 
  Views="0" UpVotes="760" DownVotes="315" AccountId="-1" />

我目前得到的输出看起来像这样(这些换行符在输出中):

  -1 | 1 | 2010-11-18T19:05:26.543 | Community | 2010-11-18T19:05:26.543 | on the server farm | <p>Hi, I'm not really a person.</p>

<p>I'm a background process that helps keep this site clean!</p>

<p>I do things like</p>

<ul>
<li>Randomly poke old unanswered questions every hour so they get some attention</li>
<li>Own community questions and answers so nobody gets unnecessary reputation from them</li>
<li>Own downvotes on spam/evil posts that get permanently deleted</li>
<li>Own suggested edits from anonymous users</li>
<li><a href="http://meta.stackexchange.com/a/92006">Remove abandoned questions</a>    </li>
</ul>
 | 0 | 760 | 315 | -1 | 

我的样式表是:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="row">
  <xsl:for-each select="@*">
    <xsl:value-of select="."/>
    <xsl:text> | </xsl:text>
    </xsl:for-each>
  <xsl:text>&#xA;</xsl:text>
</xsl:template>

</xsl:stylesheet>

如果我必须为HTML-y属性(在本例中为AboutMe)编写特殊处理,那么可以选择“在输入文件中找到它时保留文本”的一般解决方案,因为我我希望为几个不同的XML输入文件使用相同的样式表。我需要转换&lt; row&gt;所有人都出现在输出文件的一行上。

1 我知道我在这里有另一个问题 - 如果管道出现在其中一个文本字段中会怎么样,因为它肯定会在某个时候出现?我可以自由地使用任何单个字符作为分隔符;我现在正在使用烟斗,直到我解决了这个问题。

1 个答案:

答案 0 :(得分:1)

您可以使用translate()来替换字符,而不是复制属性1:1,而<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <xsl:template match="row"> <xsl:for-each select="@*"> <xsl:value-of select="translate(., '&#xA;&#xD;', ' ')"/> <xsl:text> | </xsl:text> </xsl:for-each> <xsl:text>&#xA;</xsl:text> </xsl:template> </xsl:stylesheet> 用空格字符替换字符,在这种情况下是返回字符和换行符:

<sort />

还有一个注意事项:您可能希望添加一个<xsl:for-each select="@*">,其中包含您想要的任何条件作为{{1}}的第一个子元素,以便为所有行获取相同的列顺序。