我有一个使用System.Xml.Xsl.XslCompiledTransform
转换为XML的XSLT。问题是带空格的标签会转换为空标签。下面是重现问题的最小样本。
原始数据:
<data>
<content>A</content>
<content> </content>
<content>B</content>
</data>
输出数据:
<?xml version="1.0" encoding="utf-8"?>
<data>
<content>A</content>
<content />
<content>B</content>
</data>
第二个标签错了!这个空间不能那样吃。
XSLT :
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:preserve-space elements="content"/>
<xsl:template match="//data">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
XSLT错了吗?或者我应该责怪.NET XSL转换器(我已尝试过3.5 SP1和4.0)?
请帮忙!
答案 0 :(得分:2)
您需要包含(在顶级):
<xsl:preserve-space elements="content"/>
如果有多个节点类型必须保留空格,请将它们列在由空格分隔的elements
属性中。这是documented here。
答案 1 :(得分:2)
如果您使用的是msxml,则默认情况下会记录与xml规范不一致的内容并删除空白区域。您可以将xml:space="preserve"
添加到元素中,以便正确处理该文件中的空格,或者通过API调用msxml(但如果在Internet Explorer中直接解析xml则不行)将其preserveWhitespace属性设置为true {{3 }}
与空格问题无关
<xsl:template match="//data/content">
<xsl:element name="{title}">
<xsl:apply-templates select="//data/content"/>
</xsl:element>
</xsl:template>
永远不会被执行,因为匹配data
的模板只是复制整个文档,而不是递归地应用模板。如果 被执行,它将无限循环,如上所述,对于每个内容元素,将模板应用于每个内容元素。
UPDATE 如果你不需要保留确切的空白区域,只需要放入一个空格使其非空,那么你可以通过在样式表中放回空格来纠正破解的解析,先修复一下,这样就可以递归地应用模板,然后为空内容元素添加一个额外的模板,通过添加空格使它们非空。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="content[not(node())]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:text> </xsl:text>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:2)
正如大卫指出的那样,问题是在进入XSLT之前空间被剥离了。使用.NET时的解决方案是使用XmlReader
来读取输入XML - 这段代码可以解决问题:
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load(@"c:\temp\space.xslt");
using (XmlReader reader = XmlReader.Create(@"c:\temp\spaceSample.xml")) {
using (XmlWriter writer = XmlWriter.Create(@"c:\temp\space.xml")) {
transform.Transform(reader, writer);
}
}
输入文件中的spaceSample.xml
,space.xml
是输出,space.xslt
是转换。
(使用.NET 4.0测试)