2012-03-19 7 views
0

複数の同一要素を含むXML入力ファイルを、すべて同じ要素を1つに結合する新しいXMLファイルに変換しようとしました。複数の同一要素を持つXML入力を同じ要素のないXML出力に変換する方法

<?xml version="1.0" encoding="UTF-8"?> 

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" omit-xml-declaration="no" indent="yes"/> 
<xsl:preserve-space elements="*"/> 
<xsl:template match="InputShipmentSchedule"> 
    <xsl:call-template name="CreateShipmentScheduleXmlns"/> 
</xsl:template> 

<xsl:template name="CreateShipmentScheduleXmlns"> 
    <xsl:element name="Output_Data"> 
     <xsl:element name="ShipmentSchedule"> 
       <xsl:call-template name="part_detail_template"> 
        <xsl:with-param name="currentPartLine" select="DataArea/ShipmentSchedule/ShipmentScheduleLine"/> 
        <xsl:with-param name="nextPartLine" select="DataArea/ShipmentSchedule/ShipmentScheduleLine/following-sibling::ShipmentScheduleLine"/> 
       </xsl:call-template>     
     </xsl:element> <!-- ShipmentSchedule tag end --> 
    </xsl:element> <!-- Output_Data tag end --> 
</xsl:template> <!-- CreateShipmentScheduleXmlns template end --> 

<xsl:template name="part_detail_template"> 
    <xsl:param name="currentPartLine"/> 
    <xsl:param name="nextPartLine"/> 
    <xsl:element name="Part_Detail"> <!-- Part_Detail tag start --> 
     <xsl:variable name="part_no" select="$currentPartLine/ManufacturingItem/ItemID/ID"/> 
     <xsl:element name="part_no"> 
      <xsl:attribute name="value"> 
       <xsl:value-of select="$part_no"/> 
      </xsl:attribute> 
     </xsl:element> 
    </xsl:element> <!-- Part_Detail tag end --> 
    <xsl:variable name="currentItem" select="$currentPartLine/ManufacturingItem/ItemID/ID"/> 
    <xsl:variable name="nextItem" select="$nextPartLine/ManufacturingItem/ItemID/ID"/> 
    <xsl:choose>    
     <xsl:when test="$nextPartLine and $nextItem != $currentItem"> 
      <xsl:call-template name="part_detail_template"> 
       <xsl:with-param name="currentPartLine" select="$nextPartLine"/> 
       <xsl:with-param name="nextPartLine" select="$nextPartLine/following-sibling::ShipmentScheduleLine"/> 
      </xsl:call-template> 
     </xsl:when> 
    </xsl:choose> 
</xsl:template> <!-- part_detail_template tag end -->           
</xsl:stylesheet> 

しかし、次のように出力XMLファイルがまだ冗長P313503が含まれています:

<?xml version="1.0" encoding="UTF-8"?> 
<Output_Data> 
<ShipmentSchedule> 
<Part_Detail> 
<part_no value="P313503"/> 
</Part_Detail> 
<Part_Detail> 
<part_no value="P313503"/> 
</Part_Detail> 
<Part_Detail> 
<part_no value="P313504"/> 
</Part_Detail> 
</ShipmentSchedule> 
</Output_Data> 

私はドン」私は、次のXSLトランスファイルを作っ

<?xml version="1.0"?> 
<InputShipmentSchedule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 

<DataArea> 
    <ShipmentSchedule> 
     <ShipmentScheduleLine> 
      <ManufacturingItem> 
       <ItemID> 
        <ID>P313503</ID> 
       </ItemID> 
      </ManufacturingItem>     
     </ShipmentScheduleLine> 
     <ShipmentScheduleLine> 
      <ManufacturingItem> 
       <ItemID> 
        <ID>P313503</ID> 
       </ItemID> 
      </ManufacturingItem>    
     </ShipmentScheduleLine> 
     <ShipmentScheduleLine> 
      <ManufacturingItem> 
       <ItemID> 
        <ID>P313504</ID> 
       </ItemID> 
      </ManufacturingItem>    
     </ShipmentScheduleLine> 
     <ShipmentScheduleLine> 
      <ManufacturingItem> 
       <ItemID> 
        <ID>P313504</ID> 
       </ItemID> 
      </ManufacturingItem>    
     </ShipmentScheduleLine> 
    </ShipmentSchedule> 
</DataArea> 
</InputShipmentSchedule> 

であるように、入力ファイルがあります"part_no"要素( "P313503")が2回現れる理由はわかりません。出力xmlファイルに非冗長な "part_no"要素を含めることになっています。上記のxslファイルで何が間違っていましたか?どんなコメントや提案も大歓迎です。 ありがとうございます。

答えて

1
   <xsl:with-param name="currentPartLine" 
       select="DataArea/ShipmentSchedule/ShipmentScheduleLine"/> 
       <xsl:with-param name="nextPartLine" 
       select="DataArea/ShipmentSchedule/ShipmentScheduleLine/ 
            following-sibling::ShipmentScheduleLine"/> 

これらの2つの式は、同じノードセットを選択します。 DataArea/ShipmentSchedule/ShipmentScheduleLineをすべて選択します。ShipmentScheduleLineの要素は最初の要素ではないため、following-sibling::ShipmentScheduleLineを追加しても、別のノードは選択されません。

グループ化の問題は、XSLT1よりもXSLT2よりはるかに簡単ですが、何らかの理由で1になっていると仮定すると、問題は非常に簡単です。

<xsl:stylesheet version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:strip-space elements="*"/> 
<xsl:output indent="yes"/> 

<xsl:key name="n" match="ItemID" use="ID"/> 

<xsl:template match="/"> 
<Output_Data> 
    <ShipmentSchedule> 
    <xsl:for-each select="//ManufacturingItem/ItemID[generate-id()= 
      generate-id(key('n',.))]"> 
    <Part_Detail> 
    <part_no value="{.}"/> 
    </Part_Detail> 
    </xsl:for-each> 
    </ShipmentSchedule> 
</Output_Data> 
</xsl:template> 

</xsl:stylesheet> 

生成します:あなたの答えのための

$ saxon man.xml man.xsl 
<?xml version="1.0" encoding="utf-8"?> 
<Output_Data> 
    <ShipmentSchedule> 
     <Part_Detail> 
     <part_no value="P313503"/> 
     </Part_Detail> 
     <Part_Detail> 
     <part_no value="P313504"/> 
     </Part_Detail> 
    </ShipmentSchedule> 
</Output_Data> 
+0

おかげで、この溶液にあなたを導くだろう "muenchianグループ化" のためのgoogle。しかし、すべてのShipmentScheduleLineではなく、最初のノードだけを選択するために最初の式を作成するにはどうすればよいですか?私は "DataArea/ShipmentSchedule/ShipmentScheduleLine /"を試しました。出力xmlファイルの冗長な "part_no"要素( "P313503")は削除されませんでした。 – Charles

+0

DataArea/ShipmentSchedule/ShipmentScheduleLine [1]は最初の –

+0

をコメントに記載されているように選択します。数値述語を追加するとおそらく有効になりますが、完全なパスを繰り返し検索することは効率的ではなく、別のグループ化イディオム –

関連する問題