使用XSLT从SSRS / Visual Studio导出到XML

时间:2014-10-17 11:23:08

标签: xml visual-studio xslt reporting-services xslt-1.0

我试图通过Visual Studio 2008 R2(BIDS)或SSRS从RDL文件导出,使用XSLT文件创建XML。

导出会产生以下xml代码

<?xml version="1.0" encoding="utf-8"?>
<Report xsi:schemaLocation="testreport http://reportserver?%2Ftestreport&amp;rs%3AFormat=XML&amp;rc%3ASchema=True" Name="testreport"             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="testreport">
 <ProductList>
  <Details_Collection>
   <Details>
    <ID>602</ID>
    <Title>302</Title>
   </Details>
   <Details>
    <ID>603</ID>
    <Title>303</Title>
   </Details>
  </Details_Collection>
 </ProductList>
</Report> 

从这个网站上的another post我得到了以下XSLT代码:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    exclude-result-prefixes="xsi">
  <xsl:output method="xml" indent="yes" encoding="utf-8" />

  <!-- rule to suppress the undesired nodes -->
  <xsl:template match="Report|ProductList|Details_Collection">
    <xsl:apply-templates/>
  </xsl:template>

  <!-- rule to rename the Details node -->
  <xsl:template match="Details">
    <item>
      <xsl:apply-templates/>
    </item>
  </xsl:template>

  <!-- rule to copy everything else -->
  <!-- see https://stackoverflow.com/questions/857010/xsl-avoid-exporting-namespace-defintions-to-resulting-xml-documents-->
  <!-- see https://stackoverflow.com/questions/14166259/xslt-default-template-confusion -->
  <xsl:template match="*|@*">
    <xsl:element name="{name()}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <!-- rule to start the conversion and provide the wrapper tags -->
  <xsl:template match="/">
    <rss version="2.0">
      <channel>
        <xsl:apply-templates/>
      </channel>
    </rss>
  </xsl:template>

</xsl:stylesheet>

应用XSLT时,导出会生成以下XML代码

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel>
    <Report>
      <ProductList>
        <Details_Collection>
          <Details>
            <ID>602</ID>
            <Title>302</Title>
          </Details>
          <Details>
            <ID>603</ID>
            <Title>303</Title>
          </Details> 
        </Details_Collection>
      </ProductList>
    </Report>
  </channel>
</rss>

我在这里看不到什么? &#34;报告&#34;,&#34;产品列表&#34;,&#34; Details_Collection&#34;不应该出现在输出和&#34;细节&#34;元素应命名为&#34; item&#34;。似乎元素无法通过其名称进行处理(唯一的模板匹配似乎有效的元素是"/""*""/*")。我从来没有通过其名称来解决一个特定元素的问题。

我期待这样的事情:

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel>
     <item>
         <ID>602</ID>
         <Title>302</Title>
      </item>
      <item>
         <ID>603</ID>
         <Title>303</Title>
      </item> 
  </channel>
</rss>

有人能帮助我吗? 干杯 Commx

1 个答案:

答案 0 :(得分:0)

您的输入XML位于名称空间中,即默认名称空间:

<Report xmlns="testreport">

所有后代元素也将属于此命名空间。在您的情况下,重要的是元素Report和名为{testreport}Report的元素({}告诉您存在命名空间)是完全不同的元素。

因此,如果您的模板匹配

<xsl:template match="Report">

仅在名为&#34;报告&#34;的元素时触发。找到没有命名空间的。代替, 如果需要解决特定元素的名称以及它们是否在命名空间中,则需要在XSLT样式表中声明此命名空间并为这些元素名称添加前缀:

<xsl:stylesheet xmlns:tst="testreport">
  <xsl:template match="tst:Report">
    <!--...-->
  </xsl:template>
  <!--...-->
</xsl:stylesheet>

你观察到了

  

对于似乎有效的元素,唯一的模板匹配是"/""*""/*"

因为这些模式是通用的,不使用需要加前缀的特定元素名称。

XSLT样式表

更多细节:无需在样式表中重新声明xsi命名空间 - 我已将其省略。此外,一些处理器保留空白节点,导致输出格式错误 - 我已添加xsl:strip-space来解释此问题。

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:tst="testreport"
    exclude-result-prefixes="tst">
  <xsl:output method="xml" indent="yes" encoding="utf-8" />

  <xsl:strip-space elements="*"/>

  <!-- rule to suppress the undesired nodes -->
  <xsl:template match="tst:Report|tst:ProductList|tst:Details_Collection">
    <xsl:apply-templates/>
  </xsl:template>

  <!-- rule to rename the Details node -->
  <xsl:template match="tst:Details">
    <item>
      <xsl:apply-templates/>
    </item>
  </xsl:template>

  <!-- rule to copy everything else -->
  <xsl:template match="*|@*">
    <xsl:element name="{name()}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <!-- rule to start the conversion and provide the wrapper tags -->
  <xsl:template match="/">
    <rss version="2.0">
      <channel>
        <xsl:apply-templates/>
      </channel>
    </rss>
  </xsl:template>

</xsl:stylesheet>

XML输出

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
   <channel>
      <item>
         <ID>602</ID>
         <Title>302</Title>
      </item>
      <item>
         <ID>603</ID>
         <Title>303</Title>
      </item>
   </channel>
</rss>