我的要求是使用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
答案 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>