XSLT删除节点但保留内容

时间:2014-05-12 18:16:08

标签: xml xslt reporting-services

我尝试删除节点名称,但保留内容,或将节点的内容复制到其父节点。我从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。我是否有错误的X路径?

  

<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>

1 个答案:

答案 0 :(得分:3)

您的方法是正确的,但问题是名称空间之一。在XML中,您有一个默认的名称空间声明( xmlns

<Report xmlns="My_Report" Name="My report">

这意味着元素和所有后代都属于该命名空间(除非被另一个命名空间声明覆盖)。但是,在您的XSLT中,您指定了 Cell 作为模板匹配,这是在NO命名空间中查找 Cell 元素,这与不匹配带有命名空间的XML中的Cell

解决方案是使用前缀在XSLT中声明命名空间,并使用该前缀匹配 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 ,在这种情况下,假定任何没有名称空间前缀的Xpath表达式都在该默认名称空间中

这也可行......

<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中编写名称空间声明,可以将模板匹配更改为以下内容:

<xsl:template match="*[local-name()='Cell']" >