xml - XSLT 删除节点但保留内容

标签 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。我的 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/

相关文章:

java - 如何在没有从java输入xml的情况下执行xsl转换

reporting-services - 如何在SSRS中获取时区值

c++ - TIdHTTP Get 方法在加载 xml 文件时显示奇怪的字符(不显示俄语字符)

c# - XML 反序列化为列表

xml - XSLT 和 XSLFO 命名空间

reporting-services - SSRS多选参数,既可以为空也可以不为空

reporting-services - SSRS多值参数未选择默认值

JAVA:使用 XmlStreamReader 收集 xml 标记的字节偏移量

xslt - XPath 谓词 "is parent the current node?"

XSLT - 结合身份模式更改节点上下文的问题