「SmallCat」や「BigCat」などのタイプの複数の子を含むXML文書の部分を効率的に再編成する方法を探しています。ここで条件付きXML再編成
はルールがあります:生息地のノードを除く
- すべてが通過しなければなりません。属性とすべて。
- BigCatまたはSmallCatのインスタンスが2つ未満の生息地ノードを通過させる必要があります。
入力された文書には、次のようになります。
<Zoo>
<Habitat HabitatID="habitat.cage.1">
<Type>Cats</Type>
<Food>Birds</Food>
<BigCat AnimalID="Tiger.1">
<Type>Bengal</Type>
</BigCat>
<SmallCat AnimalID="bobcat.1">
<Type>Bobcat</Type>
</SmallCat>
<BodyTemp>endothermic</BodyTemp>
</Habitat>
<Habitat HabitatID="cage.2">
<Type>Cats</Type>
<Food>Birds</Food>
<SmallCat AnimalID="tabycat.1">
<Type>Tabycat</Type>
</SmallCat>
<BodyTemp>endothermic</BodyTemp>
</Habitat>
<ConsessionStand>
<Type>PopcornStand</Type>
</ConsessionStand>
</Zoo>
出力は次のようになります。
<Zoo>
<Habitat HabitatID="sub_habitat.1.habitat.cage.1">
<Type>Cats</Type>
<Food>Birds</Food>
<BigCat AnimalID="Tiger.1">
<Type>Bengal</Type>
</BigCat>
</Habitat>
<Habitat HabitatID="sub_habitat.2.habitat.cage.1">
<Type>Cats</Type>
<Food>Birds</Food>
<SmallCat AnimalID="bobcat.1">
<Type>Bobcat</Type>
</SmallCat>
</Habitat>
<Habitat HabitatID="habitat.cage.1">
<BodyTemp>endothermic</BodyTemp>
<Child>
<HabitatID>sub_habitat.1.habitat.cage.1</HabitatID>
</Child>
<Child>
<HabitatID>sub_habitat.2.habitat.cage.1</HabitatID>
</Child>
</Habitat>
<Habitat HabitatID="cage.2">
<Type>Cats</Type>
<Food>Birds</Food>
<SmallCat AnimalID="tabycat.1">
<Type>Tabycat</Type>
</SmallCat>
<BodyTemp>endothermic</BodyTemp>
</Habitat>
<ConsessionStand>
<Type>PopcornStand</Type>
</ConsessionStand>
</Zoo>
理想的なソリューションは、XSLTを使用しますが、任意の溶液(bashのは、Javascript、PHP、Pythonのだろう、ルビー、ゴー、など)は、仕事を完了するためには合理的な候補です。
ここには、約90%の作業を行う実装があります。
このソリューションは、新しいsub_habitat子ノードへの参照を持つ最初の生息地ノードを再構築しません。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Habitat[count(BigCat|SmallCat) > 1]">
<xsl:param name="i"/>
<xsl:for-each select="BigCat|SmallCat">
<xsl:choose>
<xsl:when test="self::BigCat">
<Habitat HabitatID="sub_habitat.{position()}.{../@HabitatID}">
<xsl:copy-of select="../*[not(self::SmallCat|self::BodyTemp)]"/>
</Habitat>
</xsl:when>
<xsl:when test="self::SmallCat">
<Habitat HabitatID="sub_habitat.{position()}.{../@HabitatID}">
<xsl:copy-of select="../*[not(self::BigCat|self::BodyTemp)]"/>
</Habitat>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
出力結果はここに表示されます。
<Zoo>
<Habitat HabitatID="sub_habitat.1.habitat.cage.1">
<Type>Cats</Type>
<Food>Birds</Food>
<BigCat AnimalID="Tiger.1">
<Type>Bengal</Type>
</BigCat>
</Habitat>
<Habitat HabitatID="sub_habitat.2.habitat.cage.1">
<Type>Cats</Type>
<Food>Birds</Food>
<SmallCat AnimalID="bobcat.1">
<Type>Bobcat</Type>
</SmallCat>
</Habitat>
<Habitat HabitatID="cage.2">
<Type>Cats</Type>
<Food>Birds</Food>
<SmallCat AnimalID="tabycat.1">
<Type>Tabycat</Type>
</SmallCat>
<BodyTemp>endothermic</BodyTemp>
</Habitat>
<ConsessionStand>
<Type>PopcornStand</Type>
</ConsessionStand>
</Zoo>
を持っていますか? –
@ Michael.hor257k:まず、この問題はXSLTを使用して解決できますか?私は意味のある例を示すのに十分な専門家ではない。第二に、もしそうなら、誰かが実用的な例を提供することができます。第三に、XSLTを使用して問題を解決できない場合、他の言語では最適なソリューションはどのように見えますか? – Amvoxite
"*この問題はXSLTを使用して解決できますか?*"私はできると信じていますが、これはコード作成サービスではありません。 –