我正在尝试删除节点名称,但保留内容,或者将节点的内容复制到它的父节点。我正在从 SSRS 导出 XML,并将 XSLT 文件附加到报告 RDL。我觉得我与我拥有的 xslt 非常接近。我正在尝试删除文件中经常重复的节点“Cell”。
我想要这个:
<ReportSectionAPercentLabel>
<Cell>
<losPct>0.262158054711246</losPct>
</Cell>
</ReportSectionAPercentLabel>
看起来像这样:
<ReportSectionAPercentLabel>
<losPct>0.262158054711246</losPct>
</ReportSectionAPercentLabel>
这是 XML 的摘录:
<?xml version="1.0" encoding="UTF8"?>
<Report xmlns="My_Report" Name="My report">
<ReportSectionATablix>
<ReportSectionARowGroup_Collection>
<ReportSectionARowGroup>
<losProvider>Your Enterprise</losProvider>
<ReportSectionAColumnGroup_Collection>
<ReportSectionAColumnGroup>
<ReportSectionAGroupLabel>07</ReportSectionAGroupLabel>
<ReportSectionACountLabel>
<Cell>
<ReportSectionACount>345</ReportSectionACount>
</Cell>
</ReportSectionACountLabel>
<ReportSectionAPercentLabel>
<Cell>
<losPct>0.262158054711246</losPct>
</Cell>
</ReportSectionAPercentLabel>
</ReportSectionAColumnGroup>
<ReportSectionAColumnGroup>
<ReportSectionAGroupLabel>814</ReportSectionAGroupLabel>
<ReportSectionACountLabel>
<Cell>
<ReportSectionACount>153</ReportSectionACount>
</Cell>
</ReportSectionACountLabel>
...
这是 XSLT。我的 Cell 的 Xpath 错误吗?
<xsl:template match="node()|@*" >
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="Cell" >
<xsl:apply-templates select="*" />
</xsl:template>
最佳答案
您的方法是正确的,但问题是命名空间之一。在您的 XML 中,您有一个默认 namespace 声明(xmlns)
<Report xmlns="My_Report" Name="My report">
这意味着该元素及其所有后代都属于该命名空间(除非被另一个命名空间声明覆盖)。但是,在您的 XSLT 中,您已将 Cell 指定为模板匹配项,这是在 NO 命名空间中查找 Cell 元素,该元素与您的 不匹配带有命名空间的 XML 中的单元格。
解决方案是在 XSLT 中也声明 namespace ,使用前缀,并使用该前缀匹配 Cell 元素:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rep="My_Report">
<xsl:template match="node()|@*" >
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="rep:Cell" >
<xsl:apply-templates select="*" />
</xsl:template>
</xsl:stylesheet>
或者,如果您使用的是 XSLT 2.0,则可以使用 xpath-default-namespace,在这种情况下,任何没有 namespace 前缀的 Xpath 表达式都被假定在该默认 namespace 中
这也行...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="My_Report">
<xsl:template match="node()|@*" >
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="Cell" >
<xsl:apply-templates select="*" />
</xsl:template>
</xsl:stylesheet>
如果出于某种原因,您希望避免在 XSLT 中对 namespace 声明进行编码,您可以将模板匹配更改为以下内容:
<xsl:template match="*[local-name()='Cell']" >
关于xml - XSLT 删除节点但保留内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23616009/