0

エンベロープ タグと一連のフィールドの繰り返しだけで構成されているが、グループ化されていないローカル会計システムからの出力があります。私は XSL の経験がありませんが、これに対する解決策を見つけようとしており、XSLT 2.0 で機能する解決策を見つけました。残念ながら、Access 2007 は XSLT 1.0 変換のみを受け入れるようです。

機能する XSLT 1.0 ソリューションを見つけるのを手伝ってもらえますか?

これらは、元のフラット XML の 2 つのレコードです。

<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>
</ENVELOPE>

Access にインポートするには、データを DBCFIXED から次の DBCFIXED までのレコードにグループ化する必要があります。何かのようなもの:

<InventoryDaybook>
  <record>
    <DBCFIXED>  
      <DBCDATE>1-Apr-2011</DBCDATE>
      <DBCPARTY/>
    </DBCFIXED>
    <DBCVCHTYPE>Stock Journal</DBCVCHTYPE>
    <...></...>
  </record>
  <record>
    <...></...>
  </record>
/<InventoryDaybook>

動作する XSLT 2.0 コードは次のとおりです。

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
  <InventoryDaybook>
    <xsl:for-each-group select="*" group-starting-with="DBCFIXED">
      <record>
        <xsl:copy-of select="current-group()"/>
      </record>
    </xsl:for-each-group>
  </InventoryDaybook>
</xsl:template>
</xsl:stylesheet>

XSL でできることは驚くべきことですが、私の知識は少なすぎるようです。

4

2 に答える 2

1

最初の正解を出したティムにおめでとう。ティムの意見は完全に正しいですが、XSLT 1.0 group-starting-with には 2 つの一般的な解決策があることを OP に知らせたいと思います。もう 1 つはヘッド ノードが含まれている場所です (以下を参照)。どちらが優れているかはわかりません。おそらく、ディミトルが教えてくれるでしょう。

参考までに、キーにヘッド ノードを含む別の形式を次に示します。

ヘッドノードインクルードインキー形式

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="records" match="ENVELOPE/*" use="generate-id(
            (preceding-sibling::DBCFIXED|self::DBCFIXED)[last()])" />

   <xsl:template match="/ENVELOPE">
      <InventoryDaybook>
         <xsl:apply-templates select="DBCFIXED" mode="group-head" />
      </InventoryDaybook>
   </xsl:template>

   <xsl:template match="DBCFIXED" mode="group-head">
      <record>
         <xsl:apply-templates select="key('records', generate-id())" />
      </record>
   </xsl:template>

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

非常にわずかな利点

  1. キーマッチ条件をよりシンプルに。
  2. ヘッド ノードのテンプレートの行が 1 行減ります。
  3. ヘッド ノードは、直接コピーするのではなく、apply-templates を通過します。これは、単純なコピー以上のことを行う場合に役立ちます。

非常にわずかな欠点

  1. より複雑なキー使用属性
  2. ヘッド ノードのグループ化とそのダウンストリーム処理を区別するモードを追加する必要があります。方法ではありますが、モード指示子が自己文書化を改善するため、これも利点です。
于 2012-07-24T08:31:03.790 に答える
0

これは、非 DBCFIXED 要素に一致し、最初に先行する DBCFIXED 要素をキーとして使用するxsl:keyによって、XSLT1.0 で実現できます。

<xsl:key 
    name="records" 
    match="ENVELOPE/*[not(self::DBCFIXED)]" 
    use="generate-id(preceding-sibling::DBCFIXED[1])" />

次に、個々のDBCFIXED要素を照合すると、レコードを構成する関連要素を簡単に検索できます。

<xsl:apply-templates select="key('records', generate-id())" />

ここに完全なXLSTがあります

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

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

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

入力 XML に適用すると、次のように出力されます。

<InventoryDaybook>
   <record>
      <DBCFIXED>
         <DBCDATE>1-Apr-2011</DBCDATE>
         <DBCPARTY/>
      </DBCFIXED>
      <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/>
   </record>
   <record>
      <DBCFIXED>
         <DBCDATE/>
         <DBCPARTY>ME KN YARN BL 1</DBCPARTY>
      </DBCFIXED>
      <DBCVCHTYPE/>
      <DBCVCHNO/>
      <DBCVCHREF/>
      <DBCSTNO/>
      <DBCSERVICETAXNO/>
      <DBCPANNO/>
      <DBCCSTNO/>
      <DBCNARR/>
      <DBCQTY>0.150 Kg</DBCQTY>
      <DBCRATE>566.00/Kg</DBCRATE>
      <DBCAMOUNT>-84.90</DBCAMOUNT>
      <DBCADDLCOST/>
      <DBCGROSSAMT/>
      <DBCLEDAMT/>
   </record>
</InventoryDaybook>
于 2012-07-24T07:54:58.300 に答える