使用XSLT 1.0将元素连接行和列名的平面XML表数据转换为嵌套XML
我有XML输出,表示如下输出的数据表:使用XSLT 1.0将元素连接行和列名的平面XML表数据转换为嵌套XML,xslt,xslt-1.0,xmltable,Xslt,Xslt 1.0,Xmltable,我有XML输出,表示如下输出的数据表: <results> <Row1.Name>Henry</Row1.Name> <Row1.Id>P162</Row1.Id> <Row1.Age>23</Row1.Age> <Row2.Name>John</Row2.Name> <Row2.Id>P137</Row2.Id> <Row2.Age&
<results>
<Row1.Name>Henry</Row1.Name>
<Row1.Id>P162</Row1.Id>
<Row1.Age>23</Row1.Age>
<Row2.Name>John</Row2.Name>
<Row2.Id>P137</Row2.Id>
<Row2.Age>27</Row2.Age>
<Row3.Name>Mary</Row3.Name>
<Row3.Id>L493</Row3.Id>
<Row3.Age>32</Row3.Age>
</results>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="Row" select="distinct-values(*[contains(name(),'Row')])" />
<xsl:for-each select="$Row">
<xsl:variable name="rowName" select="name()" />
<Row>
<xsl:for-each select="*[contains(name(),$Row)]">
<xsl:copy select="." />
</xsl:for-each>
</Row>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
亨利
P162
23
约翰
P137
27
玛丽
L493
32
我想把它转换成:
<results>
<Row>
<Name>Henry</Name>
<Id>P162<Id>
<Age>23</Age>
</Row>
<Row>
<Name>John</Name>
<Id>P137<Id>
<Age>27</Age>
</Row>
<Row>
<Name>Mary</Name>
<Id>L493<Id>
<Age>32</Age>
</Row>
</results>
亨利
P162
23
约翰
P137
27
玛丽
L493
32
我正在使用的应用程序迫使我使用XSLT1.0,我确信这非常简单,但我今天有一个思维障碍,所以我想我应该问问我的虚拟同事
有人有什么想法吗
注意:修改了所需的输出以不显示迭代的行号,这正是我想要的
还没有任何接近工作状态的东西。仍然在玩不同的东西
我想我可以写这样的东西:
<results>
<Row1.Name>Henry</Row1.Name>
<Row1.Id>P162</Row1.Id>
<Row1.Age>23</Row1.Age>
<Row2.Name>John</Row2.Name>
<Row2.Id>P137</Row2.Id>
<Row2.Age>27</Row2.Age>
<Row3.Name>Mary</Row3.Name>
<Row3.Id>L493</Row3.Id>
<Row3.Age>32</Row3.Age>
</results>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="Row" select="distinct-values(*[contains(name(),'Row')])" />
<xsl:for-each select="$Row">
<xsl:variable name="rowName" select="name()" />
<Row>
<xsl:for-each select="*[contains(name(),$Row)]">
<xsl:copy select="." />
</xsl:for-each>
</Row>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
要制作此文件:
<results>
<Row>
<Row1.Name>Henry</Row1.Name>
<Row1.Id>P162</Row1.Id>
<Row1.Age>23</Row1.Age>
</Row>
<Row>
<Row2.Name>John</Row2.Name>
<Row2.Id>P137</Row2.Id>
<Row2.Age>27</Row2.Age>
</Row>
<Row>
<Row3.Name>Mary</Row3.Name>
<Row3.Id>L493</Row3.Id>
<Row3.Age>32</Row3.Age>
</Row>
</results>
亨利
P162
23
约翰
P137
27
玛丽
L493
32
然后返回并删除所有带有以下内容的行前缀:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*[contains(name(),'.')]">
<xsl:variable name="Name" select="substring-after(name(),'.')" />
<xsl:element name="{$Name}">
<xsl:value-of select="." />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
但这两种转换都不起作用,而且我认为我不能将
不同的值用于XSLT 1.0这是一个分组问题,XSLT 1.0中解决此类问题的标准方法称为Muenchian分组。您可以定义一个键,该键按照您想要的方式对元素进行分组,然后使用generate id
的技巧来处理每个组中的一个元素。在这种情况下,您希望按元素名称中位于点之前的部分对元素进行分组:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:key name="elementByRow" match="/*/*"
use="substring-before(name(), '.')" />
<xsl:template match="/results">
<results>
<!-- pick out the first RowN.* element for each N -->
<xsl:apply-templates select="*[generate-id() =
generate-id(key('elementByRow', substring-before(name(), '.'))[1])]" />
</results>
</xsl:template>
<xsl:template match="*">
<Row>
<!-- process _all_ the elements that belong to this row -->
<xsl:for-each select="key('elementByRow', substring-before(name(), '.'))">
<xsl:element name="{substring-after(name(), '.')}">
<xsl:value-of select="." />
</xsl:element>
</xsl:for-each>
</Row>
</xsl:template>
</xsl:stylesheet>
您能否更新您的问题,向我们展示您使用XSL的尝试?我们可能能够对您当前的XSL进行简单的更改,而不是自己设计整个XSL。您会发现,通过这种方式,您会得到更多更好的答案。@user2960730很高兴它奏效了,也感谢您修复了我的打字错误。如果你的问题现在解决了,你可以考虑通过点击左边的刻度标记来接受这个答案。它不仅是奖励帮助你的人的一种方式,还让其他人一眼就知道问题已经解决了。谢谢!对不起,我忘了。:)