使用Visual Studio在开发期间执行转换,生成的xml包含目标中源xml的文本,该文本包含在与我的模板条件不匹配的标记中
我希望我在第一个模板中选择 Group ,以查找 CrystalReport 的直接子项名为 Group 的任何元素并传递它们在应用模板调用中。我知道我的第二个模板上的匹配过滤器只会接受属于 Level = 1 的 Group 并将其写出来。我希望忽略其他一切。
为什么“不是这个”出现在我的输出中?
源
<?xml version="1.0" encoding="utf-8" ?>
<!--
UPDATE: Note that adding the xmlns attribute causes all output
to disappear unless you use Chris's second solution.
-->
<CrystalReport xmlns="urn:crystal-reports:schemas:report-detail" >
<Group Level="1">
<GroupHeader>
<Section>
<Field FieldName="apple" />
</Section>
</GroupHeader>
<Group Level="2">
not this
</Group>
</Group>
</CrystalReport>
变换
<?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:strip-space elements="*"/>
<xsl:template match="/CrystalReport">
<root>
<xsl:apply-templates select="Group"/>
</root>
</xsl:template>
<xsl:template match="Group[@Level='1']/GroupHeader">
<tag1><xsl:value-of select="Section/Field/@FieldName"/></tag1>
</xsl:template>
</xsl:stylesheet>
输出
<?xml version="1.0" encoding="utf-8"?>
<root>
<tag1>apple</tag1>
not this
</root>
答案 0 :(得分:2)
您正面临着XML解析器的内置模板正在发挥作用的问题。您将模板应用于所有Group
元素,但仅使用您自己的模板捕获其中一个元素。另一个由默认模板处理,这些模板输出所有节点的值。我建议你改变
<xsl:template match="/CrystalReport">
到
<xsl:template match="/">
这将覆盖产生额外输出的根默认模板。您可以在http://www.w3.org/TR/xslt#built-in-rule
找到有关内置模板规则的更多信息然后覆盖基本的text()模板,这样你最终的XSLT看起来有点像这样
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="CrystalReport/Group"/>
</root>
</xsl:template>
<xsl:template match="Group[@Level='1']/GroupHeader">
<tag1>
<xsl:value-of select="Section/Field/@FieldName"/>
</tag1>
</xsl:template>
<xsl:template match="text()"/>
<强>更新强>
或者甚至更简单,你可以匹配所需的元素并使用类似的东西
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/CrystalReport">
<root>
<xsl:apply-templates select="Group[@Level='1']/GroupHeader"/>
</root>
</xsl:template>
<xsl:template match="GroupHeader">
<tag1>
<xsl:value-of select="Section/Field/@FieldName"/>
</tag1>
</xsl:template>
这将保留默认的text()模板,非常方便。
答案 1 :(得分:0)
尝试
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:crystal="urn:crystal-reports:schemas:report-detail">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/crystal:CrystalReport">
<root>
<xsl:apply-templates select="crystal:Group[@Level='1']/crystal:GroupHeader"/>
</root>
</xsl:template>
<xsl:template match="crystal:GroupHeader">
<tag1>
<xsl:value-of select="crystal:Section/crystal:Field/@FieldName"/>
</tag1>
</xsl:template>