0

XSLTを使用してXMLドキュメントを変換しようとしていますが、XMLドキュメントで実行する処理タスクが複数あるため、問題が発生しています。

これが私が達成しようとしているステップです(申し訳ありませんが、これが可能かどうか、または他の手段を試す必要があるかどうかはわかりません):

1-すべての要素を削除/削除し、隣接する要素を次の要素<group>に配置/移動します<relation><filter>

2-呼び出されたと<filter>内の2つの要素ですべての要素を並べ替えます<relation><filtertype>

3-要素を追加し直し、要素を最初の要素から引き出すことによって、すべての<filter>要素を再グループ化します。<relation><filtertype><group><relation><filter><group>

つまり、既存のすべてのグループ化を元に戻し、すべてのフィルター要素をfiltertypeとrelationのように並べ替えてから、最初のグループ要素に移動されるリレーション要素が必要であることを認識して、共通のfiltertypeとrelationでフィルターを再グループ化しようとしています。最初のフィルター要素からグループ要素へ

紛らわしい場合は申し訳ありませんが、私のサンプルは以下のとおりです(事前に感謝します)

入力XML

<mainXML>
   <version major="1" minor="0" build="0" revision="0"/>
   <id>30</id>
   <set>Partial</set>
   <evaluate>True</evaluate>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>01001</value>
         </action>
      </filter>
      <filter>
         <relation>Or</relation>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>LessThanOrEqualTo</operator>
            <value>26886</value>
         </action>
      </filter>
   </group>
   <group>
      <relation>Or</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>30001</value>
         </action>
      </filter>
   </group>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Grouping</filtertype>
         <action>
            <type>Mailing</type>
            <operator>DoNotBelongTo</operator>
            <groupingid>1133519</groupingid>
         </action>
      </filter>
      <filter>
         <relation>And</relation>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
            <operator>Bill</operator>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
      <filter>
         <relation>Or</relation>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>       
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
   </group>
</mainXML>

必要な出力XML

<mainXML>
   <version major="1" minor="0" build="0" revision="0"/>
   <id>30</id>
   <set>Partial</set>
   <evaluate>True</evaluate>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
            <operator>Bill</operator>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
   </group>
   <group>
      <relation>Or</relation>
      <filter>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
   </group>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Grouping</filtertype>
         <action>
            <type>Mailing</type>
            <operator>DoNotBelongTo</operator>
            <groupingid>1133519</groupingid>
         </action>
      </filter>
   </group>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>01001</value>
         </action>
      </filter>
   </group>
   <group>
      <relation>Or</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>LessThanOrEqualTo</operator>
            <value>26886</value>
         </action>
      </filter>
      <filter>
         <relation>Or</relation>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>30001</value>
         </action>
      </filter>
   </group>
</mainXML>
4

1 に答える 1

0

この変換:

<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:key name="kFilterRel" match="filter"
  use="concat(filtertype,'+'
              , (preceding-sibling::*[1]
                            [self::relation]
               | relation
                )[1]
              )"/>

 <xsl:template match="node()|@*" name="identity">
  <xsl:param name="pPos"/>
  <xsl:copy>
   <xsl:apply-templates select="node()|@*">
     <xsl:with-param name="pPos" select="$pPos"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <xsl:copy>
   <xsl:apply-templates select="@*|*[not(self::group)]"/>

   <xsl:apply-templates select=
     "*/filter
        [generate-id()
        =
         generate-id(key('kFilterRel',
                         concat(filtertype,'+'
                                , (preceding-sibling::*[1]
                                             [self::relation]
                                  | relation
                                  )[1]
                               )
                         )
                         [1]
                     )]">
    <xsl:sort select="filtertype"/>
    <xsl:sort select="(preceding-sibling::*[1]
                                   [self::relation]
                     | relation)[last()]"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="filter">
  <group>
    <xsl:variable name="vRelation"
        select="(preceding-sibling::*[1][self::relation]
               | relation)[last()]"/>
    <xsl:copy-of select="$vRelation"/>
    <xsl:apply-templates mode="inGroup" select=
     "key('kFilterRel',
          concat(filtertype,'+'
                 , (preceding-sibling::relation[1]
                   | relation
                   )[last()]
                )
         )">
       <xsl:with-param name="pRel" select="$vRelation"/>
     </xsl:apply-templates>
  </group>
 </xsl:template>

 <xsl:template match="filter" mode="inGroup">
  <xsl:param name="pRel"/>

  <filter>
      <xsl:if test="not(relation) and position() > 1">
       <xsl:copy-of select="$pRel"/>
      </xsl:if>
      <xsl:apply-templates>
       <xsl:with-param name="pPos" select="position()"/>
      </xsl:apply-templates>
  </filter>
 </xsl:template>

 <xsl:template match="relation">
  <xsl:param name="pPos"/>

  <xsl:if test="$pPos > 1">
   <xsl:copy-of select="."/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

提供された XML ドキュメントに適用した場合:

<mainXML>
   <version major="1" minor="0" build="0" revision="0"/>
   <id>30</id>
   <set>Partial</set>
   <evaluate>True</evaluate>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>01001</value>
         </action>
      </filter>
      <filter>
         <relation>Or</relation>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>LessThanOrEqualTo</operator>
            <value>26886</value>
         </action>
      </filter>
   </group>
   <group>
      <relation>Or</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>30001</value>
         </action>
      </filter>
   </group>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Grouping</filtertype>
         <action>
            <type>Mailing</type>
            <operator>DoNotBelongTo</operator>
            <groupingid>1133519</groupingid>
         </action>
      </filter>
      <filter>
         <relation>And</relation>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
            <operator>Bill</operator>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
      <filter>
         <relation>Or</relation>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
   </group>
</mainXML>

必要な正しい結果が生成されます。

<mainXML>
   <version major="1" minor="0" build="0" revision="0"/>
   <id>30</id>
   <set>Partial</set>
   <evaluate>True</evaluate>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
            <operator>Bill</operator>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
   </group>
   <group>
      <relation>Or</relation>
      <filter>
         <filtertype>Action</filtertype>
         <campaign>
            <campaignid>1509779</campaignid>
         </campaign>
         <action>
            <status>DoNot</status>
         </action>
         <operator>AfterNHour</operator>
         <value>36</value>
      </filter>
   </group>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Grouping</filtertype>
         <action>
            <type>Mailing</type>
            <operator>DoNotBelongTo</operator>
            <groupingid>1133519</groupingid>
         </action>
      </filter>
   </group>
   <group>
      <relation>And</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>01001</value>
         </action>
      </filter>
   </group>
   <group>
      <relation>Or</relation>
      <filter>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>LessThanOrEqualTo</operator>
            <value>26886</value>
         </action>
      </filter>
      <filter>
         <relation>Or</relation>
         <filtertype>Search</filtertype>
         <attributeid>32900</attributeid>
         <action>
            <type>Numeric</type>
            <operator>GreaterThanOrEqualTo</operator>
            <value>30001</value>
         </action>
      </filter>
   </group>
</mainXML>
于 2013-02-12T05:46:36.210 に答える