0

会計システムからのXML出力をAccessにインポートできるXMLに変換しようとしています。残念ながら、Accessは変換にXSL 1.0しか受け入れないため、XSL2.0ソリューションをXSL1.0で機能するものに変換するための支援をすでに求めています。(グループ化の問題)。そこでのソリューションは、Accessのインポートに必要だと思ったものに対して完全に機能しました。

Accessのインポートは現在機能していますが、データがまだ実際には使用できない形式になっていることに気付きました。データはヘッダー行とサブ行で構成され、ヘッダーデータは入力されません。ただし、意味のある集計を行うには、データを入力する必要があります。

Accessにインポートされた現在のXMLは次のようになります。

DBCDATE     |DBBCPARTY         |DBCVCHTYPE     |DBCVCHNO   |DBCVCHREF    
1-Apr-2011  |                  |Stock Journal  |1          |             
            |ME KN YARN B      |               |           |             
            |ME KN YARN G      |               |           |             
            |ME KN YARN I      |               |           |             
3-Apr-2011  |                  |Stock Journal  |2          |903          
            |TIB Raw Wool      |               |           |             
            |ME KN YARN D      |               |           |             

ヘッダー行のフィールドは、サブ行(DBCDATE、DBCVCHTYPE、DBCVCHNO、DBCVCHREF、DBCNARR)にもコピーする必要があります。

AccessのVBAプログラミングでこれを行うことも、データをExcelにエクスポートして数式を適用することもできますが、データは非常に大きく、さらに多くのデータを抽出することを検討しています。そして、それは柔軟性が低くなります。また、問題はおそらく、すでにグループ化されたXMLをさらにグループ化する方向に向かっています(現在、InventoryDaybookタグ構造の形式でインポート可能な行にグループ化されています。

つまり、これは元のXMLでした。編集:テストを改善するための拡張XMLフラグメント

<ENVELOPE>
  <DBCFIXED>  <DBCDATE>1-Apr-2011</DBCDATE>
    <DBCPARTY></DBCPARTY>
  </DBCFIXED>
  <DBCVCHTYPE>Stock Journal</DBCVCHTYPE>
  <DBCVCHNO>1</DBCVCHNO>
  <DBCVCHREF></DBCVCHREF>
  <DBCSTNO></DBCSTNO>
  <DBCSERVICETAXNO></DBCSERVICETAXNO>
  <DBCPANNO></DBCPANNO>
  <DBCCSTNO></DBCCSTNO>
  <DBCNARR>Opening balance transfar</DBCNARR>
  <DBCQTY>0.000 Kg</DBCQTY>
  <DBCRATE></DBCRATE>
  <DBCAMOUNT></DBCAMOUNT>
  <DBCADDLCOST></DBCADDLCOST>
  <DBCGROSSAMT></DBCGROSSAMT>
  <DBCLEDAMT></DBCLEDAMT>
  <DBCFIXED>  <DBCDATE></DBCDATE>
    <DBCPARTY>ME KN YARN BL 1</DBCPARTY>
  </DBCFIXED>
  <DBCVCHTYPE></DBCVCHTYPE>
  <DBCVCHNO></DBCVCHNO>
  <DBCVCHREF></DBCVCHREF>
  <DBCSTNO></DBCSTNO>
  <DBCSERVICETAXNO></DBCSERVICETAXNO>
  <DBCPANNO></DBCPANNO>
  <DBCCSTNO></DBCCSTNO>
  <DBCNARR></DBCNARR>
  <DBCQTY>0.150 Kg</DBCQTY>
  <DBCRATE>566.00/Kg</DBCRATE>
  <DBCAMOUNT>-84.90</DBCAMOUNT>
  <DBCADDLCOST></DBCADDLCOST>
  <DBCGROSSAMT></DBCGROSSAMT>
  <DBCLEDAMT></DBCLEDAMT>
  <DBCFIXED>  <DBCDATE>1-Apr-2011</DBCDATE>
    <DBCPARTY></DBCPARTY>
  </DBCFIXED>
  <DBCVCHTYPE>Stock Journal</DBCVCHTYPE>
  <DBCVCHNO>2</DBCVCHNO>
  <DBCVCHREF>903</DBCVCHREF>
  <DBCSTNO></DBCSTNO>
  <DBCSERVICETAXNO></DBCSERVICETAXNO>
  <DBCPANNO></DBCPANNO>
  <DBCCSTNO></DBCCSTNO>
  <DBCNARR>Opening balance transfar</DBCNARR>
  <DBCQTY>0.000 Kg</DBCQTY>
  <DBCRATE></DBCRATE>
  <DBCAMOUNT></DBCAMOUNT>
  <DBCADDLCOST></DBCADDLCOST>
  <DBCGROSSAMT></DBCGROSSAMT>
  <DBCLEDAMT></DBCLEDAMT>
  <DBCFIXED>  <DBCDATE></DBCDATE>
    <DBCPARTY>ME KN YARN BL 1</DBCPARTY>
  </DBCFIXED>
  <DBCVCHTYPE></DBCVCHTYPE>
  <DBCVCHNO></DBCVCHNO>
  <DBCVCHREF></DBCVCHREF>
  <DBCSTNO></DBCSTNO>
  <DBCSERVICETAXNO></DBCSERVICETAXNO>
  <DBCPANNO></DBCPANNO>
  <DBCCSTNO></DBCCSTNO>
  <DBCNARR></DBCNARR>
  <DBCQTY>0.260 Kg</DBCQTY>
  <DBCRATE>26.00/Kg</DBCRATE>
  <DBCAMOUNT>-8.70</DBCAMOUNT>
  <DBCADDLCOST></DBCADDLCOST>
  <DBCGROSSAMT></DBCGROSSAMT>
  <DBCLEDAMT></DBCLEDAMT>
  <DBCFIXED>  <DBCDATE></DBCDATE>
    <DBCPARTY>ME KN YARN BL 1</DBCPARTY>
  </DBCFIXED>
  <DBCVCHTYPE></DBCVCHTYPE>
  <DBCVCHNO></DBCVCHNO>
  <DBCVCHREF></DBCVCHREF>
  <DBCSTNO></DBCSTNO>
  <DBCSERVICETAXNO></DBCSERVICETAXNO>
  <DBCPANNO></DBCPANNO>
  <DBCCSTNO></DBCCSTNO>
  <DBCNARR></DBCNARR>
  <DBCQTY>0.360 Kg</DBCQTY>
  <DBCRATE>21.00/Kg</DBCRATE>
  <DBCAMOUNT>-45.80</DBCAMOUNT>
  <DBCADDLCOST></DBCADDLCOST>
  <DBCGROSSAMT></DBCGROSSAMT>
  <DBCLEDAMT></DBCLEDAMT>
</ENVELOPE>

これはXSL(XSLT 1.0)であり、ソリューションから少し変更されています。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
   <xsl:key name="records" match="ENVELOPE/*[not(self::DBCFIXED)]" use="generate-id(preceding-sibling::DBCFIXED[1])" />
   <xsl:template match="/ENVELOPE">
      <Data>
         <xsl:apply-templates select="DBCFIXED" />
      </Data>
   </xsl:template>

   <xsl:template match="DBCFIXED">
      <InventoryDaybook>
         <xsl:copy-of select="./*" />
         <xsl:apply-templates select="key('records', generate-id())" />
      </InventoryDaybook>
   </xsl:template>

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

編集:結果のXMLを提供しました(不足している結果のXMLを指摘してくれてありがとうMartin)

最終的なXMLは次のようになります。InventoryDaybookラッピングタグは、日付、バウチャータイプ、バウチャー番号、バウチャー参照、およびナレーションに関する情報を含む「ヘッダー」タグにさらに区別されています。これらのフィールドDBCDATE、DBCVCHTYPE、DBCVCHNO、DBCVCHREF、DBCNARRは、「サブ」行を表す他のInventoryDaybookラッピングタグにコピーする必要があります。「ヘッダー」はDBCDATEで識別できます-このフィールドはヘッダー行にのみ設定されます。

<Data>
   <InventoryDaybook name="header">
      <DBCDATE>1-Apr-2011</DBCDATE>
      <DBCPARTY/>
      <DBCVCHTYPE>Stock Journal</DBCVCHTYPE>
      <DBCVCHNO>1</DBCVCHNO>
      <DBCVCHREF/>
      <DBCSTNO/>
      <DBCSERVICETAXNO/>
      <DBCPANNO/>
      <DBCCSTNO/>
      <DBCNARR>Opening balance transfar</DBCNARR>
      <DBCQTY>0.000 Kg</DBCQTY>
      <DBCRATE/>
      <DBCAMOUNT/>
      <DBCADDLCOST/>
      <DBCGROSSAMT/>
      <DBCLEDAMT/>
   </InventoryDaybook>
   <InventoryDaybook name="sub">
      <DBCDATE>1-Apr-2011</DBCDATE>
      <DBCPARTY>ME KN YARN BL 1</DBCPARTY>
      <DBCVCHTYPE>Stock Journal</DBCVCHTYPE>
      <DBCVCHNO>1</DBCVCHNO>
      <DBCVCHREF/>
      <DBCSTNO/>
      <DBCSERVICETAXNO/>
      <DBCPANNO/>
      <DBCCSTNO/>
      <DBCNARR>Opening balance transfar</DBCNARR>
      <DBCQTY>0.150 Kg</DBCQTY>
      <DBCRATE>566.00/Kg</DBCRATE>
      <DBCAMOUNT>-84.90</DBCAMOUNT>
      <DBCADDLCOST/>
      <DBCGROSSAMT/>
      <DBCLEDAMT/>
   </InventoryDaybook>
   <InventoryDaybook name="header">
      <DBCDATE>1-Apr-2011</DBCDATE>
      <DBCPARTY/>
      <DBCVCHTYPE>Stock Journal</DBCVCHTYPE>
      <DBCVCHNO>2</DBCVCHNO>
      <DBCVCHREF>903</DBCVCHREF>
      <DBCSTNO/>
      <DBCSERVICETAXNO/>
      <DBCPANNO/>
      <DBCCSTNO/>
      <DBCNARR>Opening balance transfar</DBCNARR>
      <DBCQTY>0.000 Kg</DBCQTY>
      <DBCRATE/>
      <DBCAMOUNT/>
      <DBCADDLCOST/>
      <DBCGROSSAMT/>
      <DBCLEDAMT/>
   </InventoryDaybook>
   <InventoryDaybook name="sub">
      <DBCDATE>1-Apr-2011</DBCDATE>
      <DBCPARTY>ME KN YARN BL 1</DBCPARTY>
      <DBCVCHTYPE>Stock Journal</DBCVCHTYPE>
      <DBCVCHNO>2</DBCVCHNO>
      <DBCVCHREF>903</DBCVCHREF>
      <DBCSTNO/>
      <DBCSERVICETAXNO/>
      <DBCPANNO/>
      <DBCCSTNO/>
      <DBCNARR>Opening balance transfar</DBCNARR>
      <DBCQTY>0.260 Kg</DBCQTY>
      <DBCRATE>26.00/Kg</DBCRATE>
      <DBCAMOUNT>-8.70</DBCAMOUNT>
      <DBCADDLCOST/>
      <DBCGROSSAMT/>
      <DBCLEDAMT/>
   </InventoryDaybook>
   <InventoryDaybook name="sub">
      <DBCDATE>1-Apr-2011</DBCDATE>
      <DBCPARTY>ME KN YARN BL 1</DBCPARTY>
      <DBCVCHTYPE>Stock Journal</DBCVCHTYPE>
      <DBCVCHNO>2</DBCVCHNO>
      <DBCVCHREF>903</DBCVCHREF>
      <DBCSTNO/>
      <DBCSERVICETAXNO/>
      <DBCPANNO/>
      <DBCCSTNO/>
      <DBCNARR>Opening balance transfar</DBCNARR>
      <DBCQTY>0.360 Kg</DBCQTY>
      <DBCRATE>21.00/Kg</DBCRATE>
      <DBCAMOUNT>-45.80</DBCAMOUNT>
      <DBCADDLCOST/>
      <DBCGROSSAMT/>
      <DBCLEDAMT/>
   </InventoryDaybook>
</Data>

XSLでこれを行う方法はありますか?また、これは、返されたXMLをもう一度変換することを意味するのでしょうか。このソリューションのようなものですか?二重変換の質問に対する解決策

フォーラムで同じ大きな問題を2回求めていることは承知していますが、これについてのご協力に心から感謝しています。

4

1 に答える 1

0

確かに、単一シートのパイプラインソリューションを使用できます。これは、2つのグループ化キーを使用する非パイプラインソリューションです。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />  

   <xsl:key name="header" match="ENVELOPE/*" use="generate-id(
  (preceding-sibling::DBCFIXED[DBCDATE != '']|self::DBCFIXED[DBCDATE != ''])[last()])" />
   <!-- The header key groups all the nodes belonging to a DBCDATE. This is
        a big group containing a number of 'sub' subgroups. -->

   <xsl:key name="sub" match="ENVELOPE/*" use="generate-id(
  (preceding-sibling::DBCFIXED|self::DBCFIXED)[last()])" />
   <!-- The sub key groups all the nodes under a DBCFIXED. This corresponds to
        one row in Access -->

   <xsl:template match="/*">
    <!-- This is our entry template. We gather up all the big header groups,
         and process them one group at a time in 'header' mode. -->  
      <Data>
         <xsl:apply-templates select="DBCFIXED[DBCDATE != '']" mode="header" />
      </Data>
   </xsl:template>

   <xsl:template match="DBCFIXED" mode="header">
    <!-- In this template we process the header group. -->
      <InventoryDaybook name="header">
         <!-- The first sub-group of the header group is to be marked as
              @name="header". Process the header subgroup -->
         <xsl:apply-templates select="key('sub', generate-id())" />
      </InventoryDaybook>
      <!-- Now process the other subgroups. These will be marked @name="sub". --> 
      <xsl:apply-templates select="
        key('header', generate-id()) /
        self::DBCFIXED[DBCDATE = '']"
        mode="sub" />
   </xsl:template>

   <xsl:template match="DBCFIXED" mode="sub">
      <!-- Processing a "sub" subgroup. -->
      <InventoryDaybook name="sub">
         <xsl:apply-templates select="key('sub', generate-id())" />
         <!-- The above selects the members of the subgroup. -->
      </InventoryDaybook>
   </xsl:template>

  <xsl:template match="ENVELOPE/*
    [not(self::DBCFIXED)]
    [preceding-sibling::DBCFIXED[1][DBCDATE = '']]
    [.='']">
  <!-- When we are processing a normal node in a 'sub' subgroup AND
       it doesn't have a value, pick up the default value from
       the related 'header' subgroup. This rule doesn't work for
       the DBCFIXED node. We need a special template for that. -->
      <xsl:copy>
        <xsl:value-of select="
        key('sub', generate-id(
        preceding-sibling::DBCFIXED[DBCDATE != ''][1]))        
        [local-name()=local-name(current())][1] " />
      </xsl:copy>
   </xsl:template>

   <xsl:template match="DBCFIXED">
      <!-- Flatten out the DBCFIXED node. -->
      <xsl:apply-templates select="@*|node()"/>
   </xsl:template>

   <xsl:template match="DBCDATE[ . = '']">
     <!-- Pick-up the default date from the parent DBCDATE. -->
      <xsl:copy>
        <xsl:value-of select="
        ../preceding-sibling::DBCFIXED/
        DBCDATE[ . != ''][1]" />        
      </xsl:copy>
   </xsl:template>

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

</xsl:stylesheet>
于 2012-07-25T07:59:56.510 に答える