使用XSLT转换将复杂的xml转换为表格格式

时间:2013-12-31 12:59:50

标签: xml xslt

我的要求是使用XSLT转换将复杂的XML数据转换为表格格式。我能够设计一个XSLT,但我为每个重复的字段获取多行,如Department和Center。在一行中,我得到的值为DepartmentCode和DepartmentName与CenterCode和CenterName为NULL,在另一行我得到CenterCode和CenterName的值,DepartmentCode和DepartmentName为NULL。请帮助我,为下面的复杂XML文件设计XSLT。

复杂XML文件

 <Report_Data>
  <Report_Entry> 
   <EmployeeID>78798</EmployeeID>
   <ActiveDirectoyID>sanjeev@hotmail.com</ActiveDirectoyID> 
   <PlatinumID>7598409</PlatinumID>
   <LastName>Paul</LastName>
   <Department>
    <DepartmentCode>601</DepartmentCode>
    <DepartmentName>Service</DepartmentName>
   </Department> 
   <Department>
    <DepartmentCode>602</DepartmentCode>
    <DepartmentName>Mgmt</DepartmentName>
   </Department>   
   <Center>
    <CenterCode>101</CenterCode>
    <CenterName>ABC</CenterName>
   </Center>
   <Center>
    <CenterCode>102</CenterCode>
    <CenterName>PQR</CenterName>
   </Center>
   <BusinessUnit>Sample</BusinessUnit>
   <BankAccountType>1001</BankAccountType>
 </Report_Entry>
 </Report_Data>

XSLT代码

    <xslt:stylesheet xmlns:xslt="http://www.abc.org/1999/XSL/Transform" xmlns:pqr-           xform="http://www.testing.com/2003/xform"                                                               xmlns:xs="http://www.abc.org/2001/XMLSchema" version="2.0">
   <xslt:template match="/">
   <xslt:variable name="_EmployeeID"/>
   <xslt:variable name="_DepartmentCode"/>
   <xslt:variable name="_DepartmentName"/>
   <xslt:variable name="_CenterCode"/>
   <xslt:variable name="_CenterName"/>
   <xslt:element name="results">
    <xslt:for-each select="Report_Data">
    <xslt:for-each select="Report_Entry">
      <xslt:variable name="_EmployeeID" select="EmployeeID"/>
      <xslt:for-each select="Department">
        <xslt:variable name="_DepartmentCode" select="DepartmentCode"/>
        <xslt:variable name="_DepartmentName" select="DepartmentName"/>
        <xslt:element name="result">
          <xslt:element name="EmployeeID">
            <xslt:value-of select="$_EmployeeID"/>
          </xslt:element>
          <xslt:element name="DepartmentCode">
            <xslt:value-of select="$_DepartmentCode"/>
          </xslt:element>
          <xslt:element name="DepartmentName">
            <xslt:value-of select="$_DepartmentName"/>
          </xslt:element>
          <xslt:element name="CenterCode">
            <xslt:value-of select="$_CenterCode"/>
          </xslt:element>
          <xslt:element name="CenterName">
            <xslt:value-of select="$_CenterName"/>
          </xslt:element>
        </xslt:element>
        </xslt:for-each>
        <xslt:for-each select="Center">
        <xslt:variable name="_CenterCode" select="CenterCode"/>
        <xslt:variable name="_CenterName" select="CenterName"/>
        <xslt:element name="result">
          <xslt:element name="EmployeeID">
            <xslt:value-of select="$_EmployeeID"/>
          </xslt:element>
          <xslt:element name="DepartmentCode">
            <xslt:value-of select="$_DepartmentCode"/>
          </xslt:element>
          <xslt:element name="DepartmentName">
            <xslt:value-of select="$_DepartmentName"/>
          </xslt:element>
          <xslt:element name="CenterCode">
            <xslt:value-of select="$_CenterCode"/>
          </xslt:element>
          <xslt:element name="CenterName">
            <xslt:value-of select="$_CenterName"/>
          </xslt:element>
        </xslt:element>
        </xslt:for-each>
        <xslt:element name="result">
        <xslt:element name="EmployeeID">
          <xslt:value-of select="$_EmployeeID"/>
        </xslt:element>
        <xslt:element name="DepartmentCode">
          <xslt:value-of select="$_DepartmentCode"/>
        </xslt:element>
        <xslt:element name="DepartmentName">
          <xslt:value-of select="$_DepartmentName"/>
        </xslt:element>
        <xslt:element name="CenterCode">
          <xslt:value-of select="$_CenterCode"/>
        </xslt:element>
        <xslt:element name="CenterName">
          <xslt:value-of select="$_CenterName"/>
        </xslt:element>
        </xslt:element>
        </xslt:for-each>
        </xslt:for-each>
        </xslt:element>
        </xslt:template>
        </xslt:stylesheet>

必需的输出

EmployeeID DepartmentCode DepartmentName CenterCode CenterName 78798 601服务101 ABC 78798 602 Mgmt 102 PQR

谢谢和问候 Sanjeev

1 个答案:

答案 0 :(得分:1)

问题的可能原因:如果这是XSLT 1.0处理器,请注意将select的结果分配给变量会产生Result Tree Fragment。这些无法直接导航。 EXSLT集合中有一个辅助函数,由大多数XSLT处理器实现,它将结果树片段转换为节点集,然后可以进一步探索。

http://www.exslt.org/exsl/functions/node-set/

(如果您正在使用XSLT 2.0,结果树片段和节点集合并为一个概念,临时树,并且不需要转换。)

增加:

实际上,摆脱这个问题的最简单方法是完全摆脱变量。当你在它的时候,将样式表重组为一个合适的规则系统,使用模板来描述“当你看到这个时,做那个”。在大多数情况下,如果您使用的是xsl:for-each,那么您的XSLT将比应有的更难。

此外,使用文字结果元素将使XSLT更具可读性。您不应该需要xsl:element,除非您必须在运行时以编程方式构造元素的名称和名称空间。

增加:

你的模板末尾也有一些看似多余的逻辑。基于规则的方法的另一个优点是,与子例程一样,它将代码分解为更易于阅读和验证的块。

增加:

如果您向我们展示了您实际预期的输出,那将会非常有帮助。没有它,我试图从你的代码猜测你的意图,尽管它的错误。

这可能会接近;如果没有,它至少应该让你知道一个更有经验的样式表作者将如何解决问题。警告:未经测试。

<xslt:stylesheet xmlns:xslt="http://www.abc.org/1999/XSL/Transform">

  <xslt:template match="/">
<results>
  <xslt:apply-templates select="Report_Data"/>
</results>
  </xslt:template>

  <xslt:template match="Report_Data">
<xslt:apply-templates select="/Report_Data/Report_Entry>"/>
  </xslt:template>

  <xslt:template match="Report_Entry">
<result>
  <xslt:apply-templates select="Department"/>
  <xslt:apply-templates select="Center"/>
</result>
  </xslt:template>

  <xslt:template match="Department">
<EmployeeId><xsl:value-of select="../EmployeeId"/></EmployeeId>
<xsl:copy-of select="DepartmentCode"/>
<xsl:copy-of select="DepartmentName"/>
  </xslt:template>

  <xslt:template match="Center">
<EmployeeId><xsl:value-of select="../EmployeeId"/></EmployeeId>
<xsl:copy-of select="CenterCode"/>
<xsl:copy-of select="CenterName"/>
  </xslt:template>

</xslt:stylesheet>