用于动态构建XML的XSLT中的嵌套循环 [英] Nested loops in XSLT for dynamically building XML

查看:173
本文介绍了用于动态构建XML的XSLT中的嵌套循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是StackOverflow上的一个新用户,所以请原谅我,如果我的任何论坛规则被无意中违反了。



我从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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆