Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XSLT将输入XML转换为其他XML_Xml_Xslt_Xml Serialization_Xml Parsing_Xslt 1.0 - Fatal编程技术网

使用XSLT将输入XML转换为其他XML

使用XSLT将输入XML转换为其他XML,xml,xslt,xml-serialization,xml-parsing,xslt-1.0,Xml,Xslt,Xml Serialization,Xml Parsing,Xslt 1.0,可能重复: 我是XSLT方面的专家。我已经为我感兴趣的任务寻找了一些代码,并构建了一些逻辑,但我无法获得所需的输出。如果我能得到帮助,我很高兴 输入XML: <?xml version="1.0" encoding="UTF-8"?> <t> <Data> <CD> <Artist>xxx.yyy</Artist> <song>abc</song> &

可能重复:

我是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>

xxx.yyy
abc
xxx.zzz
中国篮球协会
aaa.kkk
123
aaa.lll
456
ddd
1234
E123
户外的
棒球
0000
E123
户外的
蝙蝠石
0001
E111
户外的
硬币
0002
E111
户外的
板球
0003
E001
室内的
棒球
8888
E001
室内的
蝙蝠石
9999
E111
室内的
硬币
0001
E111
室内的
蝙蝠
0001
预期产出:

<?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>

abc
中国篮球协会
123
456
1234
0000
0001
0002
0003
8888
9999
0001
0001
编辑的预期产出:

<?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>
预期输出:
abc
中国篮球协会
123
456
1234
0000
0001
0002
0003
0001
0001
8888
9999
在上面的输入XML中:您可以注意到其中的“CD”元素和值,类似于“music”。我想得到一个如下的输出:

“CD”的示例输出:


abc
中国篮球协会
123
456
1234
在某种程度上,我可以通过门钦族的分组来实现这一点。但是,

下一个元素“Music”有子元素,其中前两个元素“Music_no”和“Music_type”匹配,然后必须对“Artist”中的值进行分组。如果它们不匹配,则必须单独分组

音乐的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>

0000
0001
0002
0003
8888
9999
0001
0001
我无法实现第二部分,因为迭代有点棘手。谢谢你的帮助

注:对于“音乐”元素,如果艺术家中的值与相应节点相似,但没有“.”,则该值必须单独分组,在“信息”之外,并应具有新的“信息”

我的工作代码:

<?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的初学者,我希望您能帮助我。

一个简单的问题应该得到一个简单的答案。此XSLT 1.0样式表

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:key name="artist-group" match="CD|Music" use="
      concat( substring-before(Artist,'.'),'|',music_no,'|',music_type)"/>

<xsl:template match="/">
  <version_3>

   <information> 
     <xsl:apply-templates select="t/Data/CD
     [generate-id(.) = generate-id( key('artist-group',
       concat( substring-before(Artist,'.'),'||'))[1])]
     [substring-before(Artist,'.')]" />
     <xsl:apply-templates select="key('artist-group','||')/self::CD" />
   </information> 

   <information> 
     <xsl:apply-templates select="t/Music
     [generate-id(.) = generate-id( key('artist-group',
       concat( substring-before(Artist,'.'),'|',music_no,'|',music_type))[1])]
     [substring-before(Artist,'.')]" />
   </information> 

   <information> 
     <xsl:apply-templates select="t/Music[substring-before(Artist,'.') = '']" />
   </information> 

  </version_3>
</xsl:template>

<xsl:template match="CD[ substring-before(Artist,'.') != ''] |
                  Music[ substring-before(Artist,'.') != '']">
 <xsl:element name="{substring-before(Artist,'.')}">
  <xsl:for-each select="key('artist-group',
     concat( substring-before(Artist,'.'),'|',music_no,'|',music_type))" >
   <xsl:element name="{substring-after(Artist,'.')}">
    <xsl:value-of select="song|value" /> 
   </xsl:element>  
  </xsl:for-each> 
 </xsl:element>
</xsl:template>


<xsl:template match="CD[ substring-before(Artist,'.')  = ''] |
                  Music[ substring-before(Artist,'.')  = '']">
 <xsl:element name="{Artist}">
  <xsl:value-of select="song|value" /> 
 </xsl:element>
</xsl:template>

</xsl:stylesheet>

。。。应用于示例输入时,将生成所需的预期输出

解释 单个键用于对音乐和CD元素进行分组。就音乐而言,它又进一步分为音乐类型和音乐类型。第一个输出信息节点来自CD元素的muenchian分组。第一个信息节点中的孤立艺术家由指令生成

公共对CD |音乐模板用于所有分组艺术家和孤立艺术家节点制作。模板对的第一个谓词[substring before(Artist,'.')!=''用于分组的艺术家,另一个用于孤立的艺术家

第二个信息节点的生成与第一个信息节点类似,只是它基于输入音乐节点,不包括孤立的艺术家

第三个信息节点的生成源于孤立的音乐节点


“孤立”是指艺术家值不包含点字符的节点。

一个简单的问题应该得到一个简单的答案。此XSLT 1.0样式表

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:key name="artist-group" match="CD|Music" use="
      concat( substring-before(Artist,'.'),'|',music_no,'|',music_type)"/>

<xsl:template match="/">
  <version_3>

   <information> 
     <xsl:apply-templates select="t/Data/CD
     [generate-id(.) = generate-id( key('artist-group',
       concat( substring-before(Artist,'.'),'||'))[1])]
     [substring-before(Artist,'.')]" />
     <xsl:apply-templates select="key('artist-group','||')/self::CD" />
   </information> 

   <information> 
     <xsl:apply-templates select="t/Music
     [generate-id(.) = generate-id( key('artist-group',
       concat( substring-before(Artist,'.'),'|',music_no,'|',music_type))[1])]
     [substring-before(Artist,'.')]" />
   </information> 

   <information> 
     <xsl:apply-templates select="t/Music[substring-before(Artist,'.') = '']" />
   </information> 

  </version_3>
</xsl:template>

<xsl:template match="CD[ substring-before(Artist,'.') != ''] |
                  Music[ substring-before(Artist,'.') != '']">
 <xsl:element name="{substring-before(Artist,'.')}">
  <xsl:for-each select="key('artist-group',
     concat( substring-before(Artist,'.'),'|',music_no,'|',music_type))" >
   <xsl:element name="{substring-after(Artist,'.')}">
    <xsl:value-of select="song|value" /> 
   </xsl:element>  
  </xsl:for-each> 
 </xsl:element>
</xsl:template>


<xsl:template match="CD[ substring-before(Artist,'.')  = ''] |
                  Music[ substring-before(Artist,'.')  = '']">
 <xsl:element name="{Artist}">
  <xsl:value-of select="song|value" /> 
 </xsl:element>
</xsl:template>

</xsl:stylesheet>

。。。应用于示例输入时,将生成所需的预期输出

解释 单个键用于对音乐和CD元素进行分组。就音乐而言,它又进一步分为音乐类型和音乐类型。第一个输出信息节点来自CD元素的muenchian分组。第一个信息节点中的孤立艺术家由指令生成

公共对CD |音乐模板用于所有分组艺术家和孤立艺术家节点制作。模板对的第一个谓词[substring before(Artist,'.')!=''用于分组的艺术家,另一个用于孤立的艺术家

第二个信息节点的生成与第一个信息节点类似,只是它基于输入音乐节点,不包括孤立的艺术家

第三个信息节点的生成源于孤立的音乐节点


“孤立”是指艺术家值不包含点字符的节点。

这是一个问得很好的问题。您已经指定了范围广泛但不太复杂的输入、预期输出和正在进行的样式表。我们没有太多被问到的问题,所以祝贺你!这个问题的变体在这里流传了一段时间。你不是在diff下发布这些问题的同一个人吗