【问题标题】:Complex xml into Tabular format using XSLT Transformation使用 XSLT 转换将复杂的 xml 转换为表格格式
【发布时间】:2013-12-31 12:59:50
【问题描述】:

我的要求是使用 XSLT 转换将复杂的 XML 数据转换为表格格式。我能够设计 XSLT,但我为每个重复字段(如部门和中心)获得了多行。在一行中,我获得了值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 管理 102 PQR

感谢和问候 桑吉夫

【问题讨论】:

  • 到目前为止你有什么?
  • 我只能设计一个简单的 XSLT,它可以为部门和中心获取多行记录。
  • 我有一个工具,我可以将列映射到输出列,并且 XSLT 会自动创建,但仅适用于简单的 XML,而不适用于像这样的复杂 XML。在自定义 XML 的情况下,该工具允许自定义XSLT 以获得所需的输出。
  • 没有看到您的 xslt 或相关 xslt 代码的 sn-p,很难为您提供帮助。
  • 我已经添加了 XSLT 代码,请看一下,让我知道我必须在 XSLT 中执行哪些更改,以便每个部门和中心都有单行以及所有列值。

标签: xml xslt


【解决方案1】:

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

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

(如果您使用的是 XSLT 2.0,Result Tree Fragments 和 Node Sets 被合并为一个概念,Temporary Trees,并且不需要转换。)

添加:

实际上,摆脱这个问题的最简单方法是完全摆脱变量。当你在做的时候,将样式表重构为一个适当的规则系统,使用模板来描述“当你看到这个,做那个”。在大多数情况下,如果您使用的是 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>

【讨论】:

  • 能否请您提供一个使用我附加的 xml 数据的示例,这真的很有帮助。
  • 我的输出应该为每个 DepartmentCode 和 DEpartmentName 包含多行,并且所有列也应该以表格格式具有与其对应的值。我已附上所需的输出格式。
猜你喜欢
  • 1970-01-01
  • 2022-11-30
  • 1970-01-01
  • 2014-04-22
  • 1970-01-01
  • 1970-01-01
  • 2015-02-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多