用于动态构建XML的XSLT中的嵌套循环 [英] Nested loops in XSLT for dynamically building XML
问题描述
我从Cognos得到一个XML文档输出想要用作Crystal Reports报表的输入。
但是,Crystal Report所需的XML格式与Cognos输出的XML格式不同。
我正在尝试转换输入XML文档(Cognos)使用XSLT获取所需的XML for Crystal。
设置上下文后,下列是Cognos中的输入XML:
<?xml version =1.0?>
< dataset>
< metadata>
< item Name =EmpId/>
< item Name =EmpName/>
< item Name =DeptName/>
< / metadata>
< data>
< rows>
< row>
< value> 1< / value>
< value> John< / value>
< value>财务< / value>
< / row>
< row>
< value> 2< / value>
< value> Peter< / value>
< value> Admin< / value>
< / row>
< / rows>
< / data>
Crystal需要所需的XML格式报告:
<?xml version =1.0?>
< dataset>
< row>
< EmpId> 1< / EmpId>
< EmpName> John< / EmpName>
< DeptName>财务< / DeptName>
< / row>
< row>
< EmpId> 2< / EmpId>
< EmpName> Peter< / EmpName>
< DeptName> Admin< / DeptName>
< / row>
< / dataset>
我在XSLT下面写了所需的转换:
<?xml version =1.0?>
< xsl:stylesheet version =1.0xmlns:xsl =http://www.w3.org/1999/XSL/Transform>
< xsl:output method =xmlindent =yes/>
< xsl:template match =/>
< dataset>
< xsl:for-each select =./ dataset / data / rows / row>
< row>
< xsl:for-each select =/ dataset / metadata / item>
< xsl:element name ={@ Name}>
< xsl:for-each select =/ dataset / data / rows / row / value>
< xsl:value-of select =。/>
< / xsl:for-each>
< / xsl:element>
< / xsl:for-each>
< / row>
< / xsl:for-each>
< / dataset>
< / xsl:template>
< / xsl:stylesheet>
我得到以下输出:
<?xml version =1.0encoding =UTF-16?>
< dataset>
< row>
< EmpId> 1JohnFinance2PeterAdmin< / EmpId>
< EmpName> 1JohnFinance2PeterAdmin< / EmpName>
< DeptName> 1JohnFinance2PeterAdmin< / DeptName>
< / row>
< row>
< EmpId> 1JohnFinance2PeterAdmin< / EmpId>
< EmpName> 1JohnFinance2PeterAdmin< / EmpName>
< DeptName> 1JohnFinance2PeterAdmin< / DeptName>
< / row>
请允许我知道我会出错。
任何帮助将被高度赞赏。
提前感谢。
注意
感谢您的支持。在定制@DimitreNovatchev提供的解决方案后,我能够获得所需的XML转换。
输入XML
<?xml version =1.0?>
< dataset xmlns =http://developer.cognos.com/schemas/xmldata/1/xmlns:xs =http://www.w3.org/2001/XMLSchema-instance>
< metadata>
< item name =Employee Id/>
< item name =Employee Name/>
< item name =部门名称/>
< / metadata>
< data>
< row>
< value> 1< / value>
< value Salutation =Dr。 >约翰< /值GT;
< value>财务< / value>
< / row>
< row>
< value> 2< / value>
< value Salutation =先生。 >彼得< /值GT;
< value> Admin< / value>
< / row>
< / data>
XSLT转换
<?xml version =1.0?>
< xsl:stylesheet version =1.0xmlns:c =http://developer.cognos.com/schemas/xmldata/1/xmlns:xsl =http://www.w3.org / 1999 / XSL /变换>
< xsl:output indent =yes/>
< xsl:strip-space elements =*/>
< xsl:variable name =vNamesselect =/ * / c:metadata / * / @ name/>
< xsl:template match =/ * / c:data>
< dataset>
< xsl:apply-templates />
< / dataset>
< / xsl:template>
< xsl:template match =c:row>
< row>
< xsl:apply-templates />
< / row>
< / xsl:template>
< xsl:template match =c:row / *>
< xsl:variable name =vPosselect =position()/>
< xsl:element name ={translate($ vNames [$ vPos],'','_')}>
< xsl:apply-templates select =@ */>
< xsl:apply-templates />
< / xsl:element>
< / xsl:template>
< xsl:template match =@ *>
< xsl:attribute name ={name()}>
< xsl:value-of select =。 />
< / xsl:attribute>
< / xsl:template>
输出XML
<?xml version =1.0encoding =UTF-16?>
< dataset xmlns:c =http://developer.cognos.com/schemas/xmldata/1/>
< row>
< Employee_Id> 1< / Employee_Id>
< Employee_Name Salutation =Dr。> John< / Employee_Name>
< Department_Name>财务< / Department_Name>
< / row>
< row>
< Employee_Id> 2< / Employee_Id>
< Employee_Name Salutation =Mr。> Peter< / Employee_Name>
< Department_Name> Admin< / Department_Name>
< / row>
希望这有帮助。 p>
I am a new user on StackOverflow, so please forgive me if I any forum rules get violated inadvertently.
I am getting an XML document output from Cognos which I want to use as Input for Crystal reports. However, the XML format needed by Crystal Report is different from the XML format of Cognos output.
I am trying to transform the Input XML document (Cognos) using XSLT to get desired XML for Crystal.
Having set the context, below is the Input XML coming from Cognos:
<?xml version="1.0"?>
<dataset>
<metadata>
<item Name="EmpId" />
<item Name="EmpName" />
<item Name="DeptName" />
</metadata>
<data>
<rows>
<row>
<value>1</value>
<value>John</value>
<value>Finance</value>
</row>
<row>
<value>2</value>
<value>Peter</value>
<value>Admin</value>
</row>
</rows>
</data>
Desired XML format required by Crystal Report:
<?xml version="1.0"?>
<dataset>
<row>
<EmpId>1</EmpId>
<EmpName>John</EmpName>
<DeptName>Finance</DeptName>
</row>
<row>
<EmpId>2</EmpId>
<EmpName>Peter</EmpName>
<DeptName>Admin</DeptName>
</row>
</dataset>
I have written below XSLT for the desired transformation:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<dataset>
<xsl:for-each select="./dataset/data/rows/row">
<row>
<xsl:for-each select="/dataset/metadata/item">
<xsl:element name="{@Name}">
<xsl:for-each select="/dataset/data/rows/row/value">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</row>
</xsl:for-each>
</dataset>
</xsl:template>
</xsl:stylesheet>
I am getting below Output:
<?xml version="1.0" encoding="UTF-16"?>
<dataset>
<row>
<EmpId>1JohnFinance2PeterAdmin</EmpId>
<EmpName>1JohnFinance2PeterAdmin</EmpName>
<DeptName>1JohnFinance2PeterAdmin</DeptName>
</row>
<row>
<EmpId>1JohnFinance2PeterAdmin</EmpId>
<EmpName>1JohnFinance2PeterAdmin</EmpName>
<DeptName>1JohnFinance2PeterAdmin</DeptName>
</row>
Kindly let me know, where I am going wrong.
Any help would be highly appreciated.
Thanks in advance.
Regards
Thanks for the support. After customizing the solution provided by @DimitreNovatchev I was able to get the desired transformation of XML. Posting the solution here so that it may help others.
Input XML
<?xml version="1.0"?>
<dataset xmlns="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
<metadata>
<item name="Employee Id" />
<item name="Employee Name" />
<item name="Department Name" />
</metadata>
<data>
<row>
<value>1</value>
<value Salutation="Dr." >John</value>
<value>Finance</value>
</row>
<row>
<value>2</value>
<value Salutation="Mr." >Peter</value>
<value>Admin</value>
</row>
</data>
XSLT Transformation
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:c="http://developer.cognos.com/schemas/xmldata/1/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vNames" select="/*/c:metadata/*/@name" />
<xsl:template match="/*/c:data">
<dataset>
<xsl:apply-templates/>
</dataset>
</xsl:template>
<xsl:template match="c:row">
<row>
<xsl:apply-templates/>
</row>
</xsl:template>
<xsl:template match="c:row/*">
<xsl:variable name="vPos" select="position()"/>
<xsl:element name="{translate($vNames[$vPos], ' ', '_')}">
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
Output XML
<?xml version="1.0" encoding="UTF-16"?>
<dataset xmlns:c="http://developer.cognos.com/schemas/xmldata/1/">
<row>
<Employee_Id>1</Employee_Id>
<Employee_Name Salutation="Dr.">John</Employee_Name>
<Department_Name>Finance</Department_Name>
</row>
<row>
<Employee_Id>2</Employee_Id>
<Employee_Name Salutation="Mr.">Peter</Employee_Name>
<Department_Name>Admin</Department_Name>
</row>
Hope this helps.
这篇关于用于动态构建XML的XSLT中的嵌套循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!