我有一个Sharepoint列表,我想通过XSL数据视图转换为JSON。
我有一个XSL递归替换函数,我用它来替换所有特殊字符(转义反斜杠,双引号到& quot;等),这给了我很好的干净JSON,它在用户浏览器中正确解析。
我需要逃脱/替换的最后一件事是新行char。新行在某些浏览器中导致解析JSON时出错。
这里有一些xsl测试title的内容是否有新的行char,如果是,我们输出一个段落:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="catalog/cd">
<xsl:if test='contains(title,"
")'>
<p>Found <xsl:value-of select="title" /></p>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
以下是一些示例xml:
<catalog>
<cd>
<title>Empire
Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<country>USA</country>
<company>RCA</company>
<price>9.90</price>
<year>1982</year>
</cd>
</catalog>
“Empire Burlesque”应该是唯一通过测试的项目,但所有三个标题都会通过if语句并输出。
修改
修改下面的解决方案,我认为如果我想在单个节点上进行搜索和替换,这应该可行吗?直到明天我才能在Sharepoint中测试它。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:for-each select="catalog/cd">
<xsl:variable name="title_clean">
<xsl:call-template name="repNL">
<xsl:with-param name="pText" select="title"/>
</xsl:call-template>
</xsl:variable>
<p><xsl:value-of select='$title_clean' /></p>
</xsl:for-each>
</xsl:template>
<xsl:template name="repNL">
<xsl:param name="pText" select="."/>
<xsl:copy-of select="substring-before(concat($pText,'
'),'
')"/>
<xsl:if test="contains($pText, '
')">
<br />
<xsl:call-template name="repNL">
<xsl:with-param name="pText" select=
"substring-after($pText, '
')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:2)
“Empire Burlesque”应该是唯一的 项目通过测试,但所有三个 标题通过if语句并且是 输出。
无法重现所谓的问题 - 使用9种不同的XSLT处理器进行测试,包括所有来自Microsoft的处理器。
反正:
此转换使用br
元素替换文本节点中的任何NL字符:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()" name="repNL">
<xsl:param name="pText" select="."/>
<xsl:copy-of select=
"substring-before(concat($pText,'
'),'
')"/>
<xsl:if test="contains($pText, '
')">
<br />
<xsl:call-template name="repNL">
<xsl:with-param name="pText" select=
"substring-after($pText, '
')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于以下XML文档(提供的文档添加了cd
以使其更有趣):
<catalog>
<cd>
<title>Line1
Line2
Line3
</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Empire
Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<country>USA</country>
<company>RCA</company>
<price>9.90</price>
<year>1982</year>
</cd>
</catalog>
产生了想要的正确结果:
<catalog>
<cd>
<title>Line1<br/> Line2<br/> Line3<br/>
</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Empire<br/> Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<country>USA</country>
<company>RCA</company>
<price>9.90</price>
<year>1982</year>
</cd>
</catalog>
<强>解释强>:
身份规则/模板“按原样”复制每个节点。
匹配任何文本节点(也称为“repNL”)的覆盖模板执行以下处理:
使用sentinel(附加到字符串的NL字符),第一个NL字符之前的子字符串(如果不包含NL字符,则为完整字符串)将被复制到输出中。
如果确实包含了NL字符,则会生成br
元素,并且该模板会在此NL字符后为剩余字符串递归调用自身。
答案 1 :(得分:0)
如果您使用的是XslCompiledTransform(C#),我相信如果您使用以下API转换XML,您将遇到此问题:
XslCompiledTransform.Transform(XmlReader input, XmlWriter results)
但是,以下API效果很好:
XslCompiledTransform.Transform(string, string);
这是有线的,但我不明白为什么......