2016-10-16 20 views
-2

タグに基づいたxmlファイルの単純な分割を探しています。 3個のタグ(オプション)は、常に繰り返して、下に示されているように分割する必要があると言う:オプションのタグに基づくXML分割

<?xml version="1.0" encoding="UTF-8"?> 
<Test> 
    <tag1>A</tag1> 
    <tag2>B</tag2> 
    <tag3>C</tag3> 
    <tag1>1</tag1> 
    <tag2>2</tag2> 
    <tag3>3</tag3> 
    <tag1>apple</tag1> 
    <tag2>orange</tag2> 
    <tag3>mango</tag3> 
</Test> 

予想される出力

<Root> 
    <Test> 
     <tag1>A</tag1> 
     <tag2>B</tag2> 
     <tag3>C</tag3> 
    </Test> 
    <Test> 
     <tag1>1</tag1> 
     <tag2>2</tag2> 
     <tag3>3</tag3> 
    </Test> 
    <Test> 
     <tag1>apple</tag1> 
     <tag2>orange</tag2> 
     <tag3>mango</tag3> 
    </Test> 
</Root> 

ここでの課題は、すべての3つのタグは任意であり、できないということです

入力ブロックに表示されます。オプションがなかった場合は - 私の質問はすでにここに答えた - Split based on just tags

すべてのヘルプは

おかげ

+1

あなたが連続しTAG1、TAG2とTAG3を持っSupposre、どのようにあなたが言うことができる彼らは、同じブロックに属している、またはそれは、例えば、TAG3が欠落しているだけ、ということです最初のブロックでtag1とtag2が2番目に欠けていますか?それは内容に基づいていますか? – Jayvee

+1

は@Jayveeと完全に同意します - あなたはすべての単一のタグ* n *の周りに ''/''を置き、一緒に属していることを証明する方法がないのであなたの質問を解決することができます。 –

+1

Re:「3つのタグ(オプション)常に繰り返す」 - オプションの場合、「常に繰り返す」ことはできません! –

答えて

0

を高く評価している私が正しく要件を理解していれば、あなたがしたい:

XSLTを1.0

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

<xsl:template match="/Test"> 
    <Root> 
     <xsl:apply-templates/> 
    </Root> 
</xsl:template> 

<xsl:template match="tag1"> 
    <Test> 
     <xsl:copy-of select=". | following-sibling::*[1][self::tag2 or self::tag3]"/> 
     <xsl:if test="following-sibling::*[1][self::tag2]"> 
      <xsl:copy-of select="following-sibling::*[2][self::tag3] "/> 
     </xsl:if> 
    </Test> 
</xsl:template> 

<xsl:template match="tag2[not(preceding-sibling::*[1][self::tag1])]"> 
    <Test> 
     <xsl:copy-of select=". | following-sibling::*[1][self::tag3]"/> 
    </Test> 
</xsl:template> 

<xsl:template match="tag3[not(preceding-sibling::*[1][self::tag2 or self::tag1])]"> 
    <Test> 
     <xsl:copy-of select="."/> 
    </Test> 
</xsl:template> 

<xsl:template match="text()"/> 

</xsl:stylesheet> 

これは、それぞれの新しいグループを開始します。これらは:

  • a tag1要素です。
  • tag2要素の直後ではありません。tag1要素です。
  • tag3要素は、tag2またはtag1要素の直後にはありません。

グループは、tag3で終了します。または、シーケンスが分割される前の最後の要素のいずれか早い方で終了します。次のテスト入力に印加

<Test> 
    <tag2>B</tag2> 
    <tag3>C</tag3> 
    <tag1>1</tag1> 
    <tag3>3</tag3> 
    <tag1>apple</tag1> 
    <tag2>orange</tag2> 
    <tag1>A</tag1> 
    <tag2>B</tag2> 
    <tag1>1</tag1> 
    <tag3>3</tag3> 
    <tag3>mango</tag3> 
    <tag1>A</tag1> 
    <tag2>B</tag2> 
    <tag3>C</tag3> 
</Test> 

XMLは、結果は次のようになります。

<?xml version="1.0" encoding="UTF-8"?> 
<Root> 
    <Test> 
     <tag2>B</tag2> 
     <tag3>C</tag3> 
    </Test> 
    <Test> 
     <tag1>1</tag1> 
     <tag3>3</tag3> 
    </Test> 
    <Test> 
     <tag1>apple</tag1> 
     <tag2>orange</tag2> 
    </Test> 
    <Test> 
     <tag1>A</tag1> 
     <tag2>B</tag2> 
    </Test> 
    <Test> 
     <tag1>1</tag1> 
     <tag3>3</tag3> 
    </Test> 
    <Test> 
     <tag3>mango</tag3> 
    </Test> 
    <Test> 
     <tag1>A</tag1> 
     <tag2>B</tag2> 
     <tag3>C</tag3> 
    </Test> 
</Root> 
+0

ありがとう!それがまさに必要なものです。私が5の代わりに5つのタグを持っていたら、すべての組み合わせで同じロジックを拡張するだけです - それは正しいのですか? –

+0

@Fkhaderあなたのグループを大きくすることができれば、よりエレガントな方法があるかもしれません。私は本当にそれを考えなかった。 「グループ」がすべての可能な組み合わせの**任意の**を持つことは本当に可能ですか?適用される制約は、多くのコードを節約する可能性があります。 –

+0

5タグのうち、少なくとも3つは常に存在します - 2,3,5としましょう。つまり、1と4はオプションです。それは多くのコードを節約できますか? –

0

ここで任意のサイズのグループで作業することができ、代替ソリューションです、その群の少なくとも1つの要素が常に存在することを条件とする。

この例では、各グループ内の最大5つの要素があり、素子tag3は、各グループに存在するであろう。

XML

<Test> 
    <tag1>A</tag1> 
    <tag2>B</tag2> 
    <tag3>C</tag3> 
    <tag4>D</tag4> 
    <tag5>E</tag5> 
    <tag2>2</tag2> 
    <tag3>3</tag3> 
    <tag5>5</tag5> 
    <tag3>C</tag3> 
    <tag3>3</tag3> 
    <tag4>4</tag4> 
    <tag5>5</tag5> 
    <tag2>B</tag2> 
    <tag3>C</tag3> 
    <tag4>D</tag4> 
    <tag1>1</tag1> 
    <tag3>3</tag3> 
    <tag5>5</tag5> 
</Test> 

XSLT 1。0

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

<xsl:key name="elems-before" match="tag1 | tag2" use="generate-id(following-sibling::tag3[1])" /> 
<xsl:key name="elems-after" match="tag4 | tag5" use="generate-id(preceding-sibling::tag3[1])" /> 

<xsl:template match="/Test"> 
    <Root> 
     <xsl:for-each select="tag3"> 
      <Test> 
       <xsl:copy-of select="key('elems-before', generate-id())"/> 
       <xsl:copy-of select="."/> 
       <xsl:copy-of select="key('elems-after', generate-id())"/> 
      </Test> 
     </xsl:for-each>    
    </Root> 
</xsl:template> 

</xsl:stylesheet> 

結果

<?xml version="1.0" encoding="UTF-8"?> 
<Root> 
    <Test> 
     <tag1>A</tag1> 
     <tag2>B</tag2> 
     <tag3>C</tag3> 
     <tag4>D</tag4> 
     <tag5>E</tag5> 
    </Test> 
    <Test> 
     <tag2>2</tag2> 
     <tag3>3</tag3> 
     <tag5>5</tag5> 
    </Test> 
    <Test> 
     <tag3>C</tag3> 
    </Test> 
    <Test> 
     <tag3>3</tag3> 
     <tag4>4</tag4> 
     <tag5>5</tag5> 
    </Test> 
    <Test> 
     <tag2>B</tag2> 
     <tag3>C</tag3> 
     <tag4>D</tag4> 
    </Test> 
    <Test> 
     <tag1>1</tag1> 
     <tag3>3</tag3> 
     <tag5>5</tag5> 
    </Test> 
</Root> 
+0

恐ろしい! - ありがとう@ michael.hor257k –

関連する問題