2017-10-24 4 views
-1
<root> 
    <food> 
     <id>fruits</id> 
     <parent /> 
     <level>1</level> 
    </food> 
    <food> 
     <id>sourFruits</id> 
     <parent>fruits</parent> 
     <level>2</level> 
    </food> 
    <food> 
     <id>sweetFruits</id> 
     <parent>fruits</parent> 
     <level>2</level> 
    </food> 
    <food> 
     <id>lemon</id> 
     <parent>sourFruits</parent> 
     <level>3</level> 
    </food> 
    <food> 
     <id>grapes</id> 
     <parent>sweetFruits</parent> 
     <level>3</level> 
    </food> 
    <food> 
     <id>oranges</id> 
     <parent>sweetFruits</parent> 
     <level>3</level> 
    </food> 
</root> 

レベルタグは、階層(形成する論理ツリーのノードレベル)を示します。 このxml(上記)を以下のような別のxmlに変換する必要があります。 画像は次のようなものです: - 果物はルート要素です。 フルーツには2つの子供がいます.SourFruitsとsweetFruitsがあります。 sourFruitsには子供レモンがあり、sweetFruitsにはオレンジとブドウが子供として含まれています。この時点では本当に混乱し入力としてフラットxmlを使用して論理階層ツリーを構築する方法はありますか?

アム...

<goodFoods> 
    <foodType> 
     <name>fruits</name> 
     <taste> 
      <tasteType>sourFruits</tasteType> 
      <fruit> 
       <fruitname>lemon</fruitname> 
      </fruit> 
     </taste> 
     <taste> 
      <tasteType>sweetFruits</tasteType> 
      <fruit> 
       <fruitname>grapes</fruitname> 
      </fruit> 
      <fruit> 
       <fruitname>oranges</fruitname> 
      </fruit> 
     </taste> 
    </foodType> 
</goodFoods> 
+2

のですか? – Steve

+1

味覚タグは間違った子供で繰り返されています。 –

+1

いいえ、これまでに得たXSLTは何ですか? – Steve

答えて

0

あなたはXSLT 3.0複合キーで、キーを使用してこれを行うことができますXSLTで、彼らのlevelによって、その親によってfoot要素を参照したいです

<xsl:key name="children" match="food" composite="yes" use="xs:integer(level), string(parent)"/> 

は、XSLTの以前のバージョンを使用すると、例えばとのレベルと親を連結した文字列のような単一のキー値を使用する必要があるだろう、大丈夫です

<xsl:key name="children" match="food" use="concat(level, '|', parent)"/> 

その後、あなたがXSLT 3と

<xsl:template match="root"> 
    <goodFoods> 
     <xsl:apply-templates select="key('children', (1, ''))"/> 
    </goodFoods> 
</xsl:template> 

<xsl:template match="food[level = 1]"> 
    <foodType> 
     <name>{id}</name> 
     <xsl:apply-templates select="key('children', (level + 1, string(id)))"/> 
    </foodType>  
</xsl:template> 

<xsl:template match="food[level = 2]"> 
    <taste> 
     <tasteType>{id}</tasteType> 
     <xsl:apply-templates select="key('children', (level + 1, string(id)))"/> 
    </taste> 
</xsl:template> 

<xsl:template match="food[level = 3]"> 
    <fruit> 
     <fruitName>{id}</fruitName> 
    </fruit> 
</xsl:template> 

完全なスタイルシートが

あるだろうXSLT 3.0となるよう、ターゲット形式に各レベルを変換し、キーを持つ子供たちを見つけることだけが必要です
<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" 
    exclude-result-prefixes="xs math" 
    expand-text="yes" 
    version="3.0"> 

    <xsl:key name="children" match="food" composite="yes" use="xs:integer(level), string(parent)"/> 

    <xsl:output indent="yes"/> 

    <xsl:template match="root"> 
     <goodFoods> 
      <xsl:apply-templates select="key('children', (1, ''))"/> 
     </goodFoods> 
    </xsl:template> 

    <xsl:template match="food[level = 1]"> 
     <foodType> 
      <name>{id}</name> 
      <xsl:apply-templates select="key('children', (level + 1, string(id)))"/> 
     </foodType>  
    </xsl:template> 

    <xsl:template match="food[level = 2]"> 
     <taste> 
      <tasteType>{id}</tasteType> 
      <xsl:apply-templates select="key('children', (level + 1, string(id)))"/> 
     </taste> 
    </xsl:template> 

    <xsl:template match="food[level = 3]"> 
     <fruit> 
      <fruitName>{id}</fruitName> 
     </fruit> 
    </xsl:template> 

</xsl:stylesheet> 

XSLT 1または2キーを使用すると、テンプレートをわずかに調整する必要があります。

<xsl:template match="food[level = 1]"> 
     <foodType> 
      <name> 
       <xsl:value-of select="id"/> 
      </name> 
      <xsl:apply-templates select="key('children', concat(level + 1, '|', id))"/> 
     </foodType>  
    </xsl:template> 

他のテンプレートを調整する方法は明らかです。

0

ないXSLTについて確認が、ここではxshでそれを行う方法は次のとおりです。

open file.xml ; 
for &{ sort :n :d :k level /root/food[parent!=""] } { 
    my $f = . ; 
    mv $f into ../food[id=$f/parent] ; 
} 

rename goodFoods /root ; 

rename fruit //food[level = 3] ; 
rename taste //food[level = 2] ; 
rename foodType //food[level = 1] ; 

rename fruitname //fruit/id ; 
rename tasteType //taste/id ; 
rename name  //foodType/id ; 

remove (//level | //parent) ; 

save :b ; 

xmllint --formatで処理した後、出力はあなたがこれまで持っている何

<goodFoods> 
    <foodType> 
    <name>fruits</name> 
    <taste> 
     <tasteType>sourFruits</tasteType> 
     <fruit> 
     <fruitname>lemon</fruitname> 
     </fruit> 
    </taste> 
    <taste> 
     <tasteType>sweetFruits</tasteType> 
     <fruit> 
     <fruitname>grapes</fruitname> 
     </fruit> 
     <fruit> 
     <fruitname>oranges</fruitname> 
     </fruit> 
    </taste> 
    </foodType> 
</goodFoods> 
関連する問題