XSLT中用于动态构建XML的嵌套循环
我是StackOverflow的新用户,如果我无意中违反了任何论坛规则,请原谅我 我从Cognos获得一个XML文档输出,我想将其用作Crystal reports的输入。 然而,Crystal Report所需的XML格式与Cognos输出的XML格式不同 我试图使用XSLT转换输入XML文档Cognos,以获得Crystal所需的XML 设置好上下文后,下面是来自Cognos的输入XML:XSLT中用于动态构建XML的嵌套循环,xslt,loops,dynamic,nested,Xslt,Loops,Dynamic,Nested,我是StackOverflow的新用户,如果我无意中违反了任何论坛规则,请原谅我 我从Cognos获得一个XML文档输出,我想将其用作Crystal reports的输入。 然而,Crystal Report所需的XML格式与Cognos输出的XML格式不同 我试图使用XSLT转换输入XML文档Cognos,以获得Crystal所需的XML 设置好上下文后,下面是来自Cognos的输入XML: <?xml version="1.0"?> <dataset> <met
<?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>
Crystal Report所需的XML格式:
<?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>
我已经为所需的转换编写了以下XSLT:
<?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>
我得到以下输出:
<?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>
请告诉我,我错在哪里
任何帮助都将不胜感激
提前谢谢
关于我将使用和机制来解决此问题。我认为,在这里,每个人都不是正确的选择
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>Finance</value>
</row>
<row>
<value>2</value>
<value>Peter</value>
<value>Admin</value>
</row>
</rows>
</data>
</dataset>
将此样式表应用于它:
<?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:apply-templates select="//row"/>
</dataset>
</xsl:template>
<xsl:template match="row">
<row>
<xsl:apply-templates select="value"/>
</row>
</xsl:template>
<xsl:template match="value">
<xsl:variable name="index">
<xsl:number/>
</xsl:variable>
<xsl:element name="{../../../../metadata/item[position() = $index]/@Name}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
您将获得以下输出:
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<row>
<EmpId>1</EmpId>
<EmpName>John</EmpName>
<DeptName>Finance</DeptName>
</row>
<row>
<EmpId>2</EmpId>
<EmpName>Peter</EmpName>
<DeptName>Admin</DeptName>
</row>
</dataset>
我通过匹配和应用某些模板创建的数据集和行元素。
让我们知道这是否对您有效
致以最良好的祝愿,
Peter我会使用和机制来解决这个问题。我认为,在这里,每个人都不是正确的选择
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>Finance</value>
</row>
<row>
<value>2</value>
<value>Peter</value>
<value>Admin</value>
</row>
</rows>
</data>
</dataset>
将此样式表应用于它:
<?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:apply-templates select="//row"/>
</dataset>
</xsl:template>
<xsl:template match="row">
<row>
<xsl:apply-templates select="value"/>
</row>
</xsl:template>
<xsl:template match="value">
<xsl:variable name="index">
<xsl:number/>
</xsl:variable>
<xsl:element name="{../../../../metadata/item[position() = $index]/@Name}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
您将获得以下输出:
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<row>
<EmpId>1</EmpId>
<EmpName>John</EmpName>
<DeptName>Finance</DeptName>
</row>
<row>
<EmpId>2</EmpId>
<EmpName>Peter</EmpName>
<DeptName>Admin</DeptName>
</row>
</dataset>
我通过匹配和应用某些模板创建的数据集和行元素。
让我们知道这是否对您有效
致以最良好的祝愿,
彼得这个简短而简单的转变:
<?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>
应用于提供的XML文档时,添加了一个缺少的结束标记,以使其格式良好:
<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>
</dataset>
生成所需的正确结果:
说明:
使用模板和XSLT模板选择机制来完成这项工作。作为XSLT中的一条规则,我们更喜欢这样做——从而获得更简单、更可扩展、更易于理解和维护的代码。这是一个几乎100%推式解决方案的示例
使用它可以一次性获得我们将经常使用的节点
保存在一个变量中供以后在其他上下文中使用-位置取决于上下文
这个简短而简单的转换:
<?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>
应用于提供的XML文档时,添加了一个缺少的结束标记,以使其格式良好:
<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>
</dataset>
生成所需的正确结果:
说明:
使用模板和XSLT模板选择机制来完成这项工作。作为XSLT中的一条规则,我们更喜欢这样做——从而获得更简单、更可扩展、更易于理解和维护的代码。这是一个几乎100%推式解决方案的示例
使用它可以一次性获得我们将经常使用的节点
保存在一个变量中供以后在其他上下文中使用-位置取决于上下文
谢谢你的支持。在定制@DimitreNovatchev提供的解决方案之后,我能够获得所需的XML转换。在此处发布解决方案,以便它可以帮助其他人 输入XML XSLT转换 输出XML
希望这能有所帮助。谢谢您的支持。在定制@DimitreNovatchev提供的解决方案之后,我能够获得所需的XML转换。在此处发布解决方案,以便它可以帮助其他人 输入XML XSLT转换 输出XML
希望这能有所帮助。您可以在此处使用xsl:key,使元素名称的查找更整洁、更高效。Peter,与其使用//row作为匹配模式,不如使用//row更简单、更等效。感谢Dimitre的提示,但如果我使用row运行上述xsl,则输出XML为空,它似乎需要/.@Peter,我只是在谈论匹配模式,而不是xsl:apply templates的select属性。使用position可能比使用xsl:number更有效,特别是当xsl:number位于结果树片段中时,这意味着将数字转换为字符串,再转换为变量中保存的树,引用变量时,首先将其转换为字符串,最后再转换为数字。您可以在此处使用xsl:key,以使元素名称的查找更整洁、更高效。Peter,与其使用//行作为匹配模式,只使用:row更简单,也相当于使用:row。谢谢Dimitre的提示,但是如果我使用row运行上面的XSL,输出XML为空,它似乎需要//。@Peter,我只讨论匹配模式,而不是XSL:apply templates的select属性。使用position可能比使用XSL:number更有效,特别是当xsl:number位于结果树片段中时,这意味着您要将一个数字转换为一个字符串,再转换为变量中的一个树,当您引用变量时,您首先要将它转换为一个字符串,最后再转换回一个数字。您好,Dimitre,将名称路径写入变量vName是否会提高性能
彼得,对不起,你什么意思?请重新措辞。@Peter,从节点集中选择第N个节点比计算具有多个反向步骤的复杂XPath表达式更有效-每次我们处理一个值。@Peter:两者都是。可读性和方便性。更短更简单。更灵活—如果由于XML文档的重新构造而需要更改选择必要名称的XPath表达式,那么我只需在变量定义中的一个位置更改XPath表达式。所有剩余的代码都将保持不变。@DimitreNovatchev,感谢您的解决方案和解释。但是,我删除了codeomit xml declaration=yes,以便在输出xml中获取代码。您好,Dimitre,将名称路径写入变量vNames中对性能更好吗?@Peter,对不起,您是什么意思?请重新措辞。@Peter,从节点集中选择第N个节点比计算具有多个反向步骤的复杂XPath表达式更有效-每次我们处理一个值。@Peter:两者都是。可读性和方便性。更短更简单。更灵活—如果由于XML文档的重新构造而需要更改选择必要名称的XPath表达式,那么我只需在变量定义中的一个位置更改XPath表达式。所有剩余的代码都将保持不变。@DimitreNovatchev,感谢您的解决方案和解释。但是,我删除了codeomit xml declaration=yes以在输出xml中获取代码。感谢这帮助我将Cognos Report Studio数据导出为xml。但是需要注意的是:输入XML在末尾缺失,XSLT转换在末尾缺失。在我纠正之前,给我的XML文档结构必须在相同的实体错误中开始和结束。这帮助我将Cognos Report Studio数据导出为XML。但是需要注意的是:输入XML在末尾缺失,XSLT转换在末尾缺失。在我纠正错误之前,提供给我的XML文档结构必须在同一实体中开始和结束