【发布时间】:2012-07-09 03:15:07
【问题描述】:
我是 XSLT 的初学者。我查看了一些我感兴趣的任务的代码并构建了一些逻辑,但我无法进入所需的输出。如果我能得到帮助,我很高兴。
输入 XML:
<?xml version="1.0" encoding="UTF-8"?>
<t>
<Data>
<CD>
<Artist>xxx.yyy</Artist>
<song>abc</song>
</CD>
<CD>
<Artist>xxx.zzz</Artist>
<song>cba</song>
</CD>
<CD>
<Artist>aaa.kkk</Artist>
<song>123</song>
</CD>
<CD>
<Artist>aaa.lll</Artist>
<song>456</song>
</CD>
<CD>
<Artist>ddd</Artist>
<song>1234</song>
</CD>
</Data>
<Music>
<music_no>E123</music_no>
<music_type>outdoor</music_type>
<Artist>bat.ball</Artist>
<value>0000</value>
</Music>
<Music>
<music_no>E123</music_no>
<music_type>outdoor</music_type>
<Artist>bat.stone</Artist>
<value>0001</value>
</Music>
<Music>
<music_no>E111</music_no>
<music_type>outdoor</music_type>
<Artist>board.coins</Artist>
<value>0002</value>
</Music>
<Music>
<music_no>E111</music_no>
<music_type>outdoor</music_type>
<Artist>board.ball</Artist>
<value>0003</value>
</Music>
<Music>
<music_no>E001</music_no>
<music_type>indoor</music_type>
<Artist>bat.ball</Artist>
<value>8888</value>
</Music>
<Music>
<music_no>E001</music_no>
<music_type>indoor</music_type>
<Artist>bat.stone</Artist>
<value>9999</value>
</Music>
<Music>
<music_no>E111</music_no>
<music_type>indoor</music_type>
<Artist>board.coins</Artist>
<value>0001</value>
</Music>
<Music>
<music_no>E111</music_no>
<music_type>indoor</music_type>
<Artist>bat</Artist>
<value>0001</value>
</Music>
</t>
预期输出:
<?xml version="1.0" encoding="UTF-8"?>
<version_3>
<information>
<xxx>
<yyy>abc</yyy>
<zzz>cba</zzz>
</xxx>
<aaa>
<kkk>123</kkk>
<lll>456</lll>
</aaa>
<ddd>1234</ddd>
</information>
<information>
<bat>
<ball>0000</ball>
<stone>0001</stone>
</bat>
<board>
<coins>0002</coins>
<ball>0003</ball>
</board>
<bat>
<ball>8888</ball>
<stone>9999</stone>
</bat>
<board>
<coins>0001</coins>
</board>
</information>
<information>
<bat>0001</bat>
</information>
</version_3>
编辑的预期输出:
Expected Output:
<?xml version="1.0" encoding="UTF-8"?>
<version_3>
<information>
<xxx>
<yyy>abc</yyy>
<zzz>cba</zzz>
</xxx>
<aaa>
<kkk>123</kkk>
<lll>456</lll>
</aaa>
<ddd>1234</ddd>
</information>
<information>
<bat>
<ball>0000</ball>
<stone>0001</stone>
</bat>
</information>
<information>
<board>
<coins>0002</coins>
<ball>0003</ball>
</board>
<board>
<coins>0001</coins>
<bat>0001</bat>
</board>
</information>
<information>
<bat>
<ball>8888</ball>
<stone>9999</stone>
</bat>
</information>
</version_3>
在上面的输入 XML 中:您可以注意到其中的“CD”元素和值,类似于“音乐”。我想得到一个看起来像这样的输出,
“CD”的示例输出:
<information>
<xxx>
<yyy>abc</yyy>
<zzz>cba</zzz>
</xxx>
<aaa>
<kkk>123</kkk>
<lll>456</lll>
</aaa>
<ddd>1234</ddd>
</information>
我可以通过 Muenchian Grouping 在某种程度上实现这一目标。但是,
下一个元素“音乐”具有子元素,其中前两个元素“music_no”和“music_type”匹配,然后必须对“艺术家”中的值进行分组。如果它们不匹配,则必须单独分组。
音乐的示例 o/p:
<information>
<bat>
<ball>0000</ball>
<stone>0001</stone>
</bat>
<board>
<coins>0002</coins>
<ball>0003</ball>
</board>
<bat>
<ball>8888</ball>
<stone>9999</stone>
</bat>
<board>
<coins>0001</coins>
</board>
</information>
<information>
<bat>0001</bat>
</information>
我无法完成第二部分,因为迭代有点棘手。感谢您的帮助。
注意:对于“音乐”元素,如果艺术家中的值与相应节点相似但没有“。”那么该值必须单独分组,它在“信息”之外,并且应该有新的“信息”
我的代码:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
<xsl:key name="kBychildName" match="CD" use="name(Artist/*[1])"/>
<xsl:key name="kByAttribs" match="Artist" use="concat(../@music_no, '+', ../@music_type)"/>
<xsl:key name="kChildByAttribsAndArtist" match="Artist/*" use="concat(../../@music_no, '+', ../../@music_type, '+', name())"/>
<xsl:template match="/">
<version_3>
<information>
<xsl:variable name="var1">
<xsl:apply-templates/>
</xsl:variable>
<xsl:apply-templates mode="pass2" select="ext:node-set($var1)/* [generate-id()=generate-id(key('kBychildName',name(Artist/*[1]))[1]) or not(Artist/*)]"/>
</information>
<information>
<xsl:variable name="var2">
<xsl:apply-templates/>
</xsl:variable>
<xsl:apply-templates mode="pass3" select="ext:node-set($var2)/*/* [generate-id() = generate-id(key('kByAttribs', concat(../@music_no, '+', ../@music_type) ) [1])] "/>
</information>
</version_3>
<!--xsl:copy-of select="//msg_debug"/-->
</xsl:template>
<xsl:template match="CD[contains(Artist,'.')]">
<CD>
<Artist>
<xsl:element name="{substring-before(Artist, '.')}">
<xsl:element name="{substring-after(Artist, '.')}">
<xsl:value-of select="song"/>
</xsl:element>
</xsl:element>
</Artist>
</CD>
</xsl:template>
<xsl:template match="CD">
<CD>
<Artist>
<xsl:element name="{Artist}">
<xsl:value-of select="song"/>
</xsl:element>
</Artist>
</CD>
</xsl:template>
<xsl:template match="CD" mode="pass2">
<xsl:apply-templates select="*/*[1]" mode="pass2"/>
</xsl:template>
<xsl:template match="Artist/*" mode="pass2">
<xsl:copy>
<xsl:copy-of select="self::*[not(*)]/text()|key('kBychildName', name())/*/*/*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Music[contains(Artist, '.')]">
<Music music_no="{music_no}" music_type="{music_type}">
<Artist>
<xsl:element name="{substring-before(Artist, '.')}">
<xsl:element name="{substring-after(Artist, '.')}">
<xsl:value-of select="value"/>
</xsl:element>
</xsl:element>
</Artist>
</Music>
</xsl:template>
<xsl:template match="Music">
<Music music_no="{music_no}" music_type="{music_type}">
<Artist>
<xsl:element name="{Artist}">
<xsl:value-of select="value"/>
</xsl:element>
</Artist>
</Music>
</xsl:template>
<xsl:template match="Artist" mode="pass3">
<!--Artist-->
<xsl:apply-templates mode="pass3" select="*[generate-id() =generate-id(key('kChildByAttribsAndArtist', concat(../../@music_no, '+', ../../@music_type,'+', name()))[1] ) ]"/>
<xsl:copy-of select="key('kByAttribs',concat(../@music_no, '+', ../@music_type) )/*[not(*)] "/>
<!--/Artist-->
</xsl:template>
<xsl:template match="Artist/*" mode="pass3">
<xsl:element name="{name()}">
<xsl:copy-of select="key('kChildByAttribsAndArtist', concat(../../@music_no, '+', ../../@music_type, '+', name()) )/* "/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
如果发现困难,我很高兴再次解释问题。作为 XSLT 的初学者,我希望你能帮助我。
【问题讨论】:
-
这是一个很好的问题。您已经指定了范围广泛但不太复杂的输入、预期输出和正在进行中的样式表。我们没有得到很多很好的问题,所以恭喜!
-
这个问题的变种已经在这里流传了一段时间。您不是同一个人在不同的用户 ID 下发布这些问题吗?我会提醒版主注意这个不需要的活动。 -1.
-
致版主:我相信
Ramana和user1510890是同一个人使用的两个不同的userId。这个人在不同的用户 ID 下不断增加非常相似的问题。我想您可能对此活动感兴趣。 -
@SeanB.Durkin:请阅读我上面的 cmets 并注意。
-
@Ruser1510890:哦,你改变了你的用户名?再次?您是如何使用我的解决方案来解决完全相同的问题的?即使您不是“Ramana”,这也是一个重复的问题。我厌倦了一遍又一遍地看到同一个问题的变体——除了为虚拟帐户获得足够的代表以便能够对其进行投票/否决之外,这没有任何意义。
标签: xml xslt xml-serialization xml-parsing xslt-1.0