0

明らかなように、XML と XSLT に関する私の知識はかなり限られています。以下の XML の各 ItemNumber/Sales Order を通過させて、各アイテムに対して 2 番目の XML が生成されるようにする変換ファイルを誰かが手伝ってくれませんか。つまり、複数の出力 xml (販売注文ごとに 1 つ) を生成する必要があります。現時点では、最初の xml の最後の品目/販売注文に対して 1 つの出力 xml しか取得していません。

翻訳する必要があるxmlは次のとおりです。

<?xml version="1.0" encoding="Windows-1252"?>
<postsalesorderssct Language='05' Language2='EN' CssStyle='' DecFormat='1' DateFormat='01' Role='01' Version='6.1.009' OperatorPrimaryRole='   '>
    <Item>
        <Key>
            <SalesOrder>197588</SalesOrder>
            <SourceWarehouse>A3</SourceWarehouse>
            <TargetWarehouse>PV</TargetWarehouse>
            <CustomerPoNumber/>
        </Key>
        <ItemNumber>000001</ItemNumber>
    </Item>
    <Item>
        <Key>
            <SalesOrder>197589</SalesOrder>
            <SourceWarehouse>A3</SourceWarehouse>
            <TargetWarehouse>HI</TargetWarehouse>
            <CustomerPoNumber/>
        </Key>
        <ItemNumber>000002</ItemNumber>
    </Item>
    <Item>
        <Key>
            <SalesOrder>197590</SalesOrder>
            <SourceWarehouse>A3</SourceWarehouse>
            <TargetWarehouse>WS</TargetWarehouse>
            <CustomerPoNumber/>
        </Key>
        <ItemNumber>000003</ItemNumber>
    </Item>
    <Item>
        <Key>
            <SalesOrder>197591</SalesOrder>
            <SourceWarehouse>A4</SourceWarehouse>
            <TargetWarehouse>HI</TargetWarehouse>
            <CustomerPoNumber/>
        </Key>
        <ItemNumber>000004</ItemNumber>
    </Item>
    <Item>
        <Key>
            <SalesOrder>197592</SalesOrder>
            <SourceWarehouse>A4</SourceWarehouse>
            <TargetWarehouse>PV</TargetWarehouse>
            <CustomerPoNumber/>
        </Key>
        <ItemNumber>000005</ItemNumber>
    </Item>
    <Item>
        <Key>
            <SalesOrder>197593</SalesOrder>
            <SourceWarehouse>A4</SourceWarehouse>
            <TargetWarehouse>WS</TargetWarehouse>
            <CustomerPoNumber/>
        </Key>
        <ItemNumber>000006</ItemNumber>
    </Item>
    <StatusOfItems>
        <ItemsProcessed>000006</ItemsProcessed>
        <ItemsInvalid>000000</ItemsInvalid>
    </StatusOfItems>
</postsalesorderssct>

現在使用している翻訳ファイルは次のとおりです。

    <?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="Windows-1252" omit-xml-declaration="yes" />
<xsl:template match="/">
<Query>
 <Key>
  <xsl:for-each select = "postsalesorderssct/Item/Key">
       <SalesOrder><xsl:value-of select="SalesOrder"/></SalesOrder>
  </xsl:for-each>
 </Key>
</Query>
</xsl:template>
</xsl:stylesheet>

以下は、初期 xml の各 ItemNumbers に必要な出力です。つまり、Sales Order 番号ごとに次のいずれかが生成される必要があります。

<Query xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORQRY.XSD">
    <Key>
        <SalesOrder>197588</SalesOrder>
        <Invoice/>
    </Key>
    <Option>
        <IncludeStockedLines>Y</IncludeStockedLines>
        <IncludeNonStockedLines>Y</IncludeNonStockedLines>
        <IncludeFreightLines>Y</IncludeFreightLines>
        <IncludeMiscLines>Y</IncludeMiscLines>
        <IncludeCommentLines>Y</IncludeCommentLines>
        <IncludeCompletedLines>Y</IncludeCompletedLines>
        <IncludeSerials>N</IncludeSerials>
        <IncludeLots>Y</IncludeLots>
        <IncludeBins>Y</IncludeBins>
        <IncludeAttachedItems>N</IncludeAttachedItems>
        <IncludeCustomForms>Y</IncludeCustomForms>
        <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms>
        <XslStylesheet/>
    </Option>
</Query>

期待して感謝します。

4

2 に答える 2

1

XSLT 2.0 を使用できる場合は、次のように動作するはずです...

XML 入力

<postsalesorderssct Language='05' Language2='EN' CssStyle='' DecFormat='1' DateFormat='01' Role='01' Version='6.1.009' OperatorPrimaryRole='   '>
    <Item>
        <Key>
            <SalesOrder>197588</SalesOrder>
            <SourceWarehouse>A3</SourceWarehouse>
            <TargetWarehouse>PV</TargetWarehouse>
            <CustomerPoNumber/>
        </Key>
        <ItemNumber>000001</ItemNumber>
    </Item>
    <Item>
        <Key>
            <SalesOrder>197589</SalesOrder>
            <SourceWarehouse>A3</SourceWarehouse>
            <TargetWarehouse>HI</TargetWarehouse>
            <CustomerPoNumber/>
        </Key>
        <ItemNumber>000002</ItemNumber>
    </Item>
    <Item>
        <Key>
            <SalesOrder>197590</SalesOrder>
            <SourceWarehouse>A3</SourceWarehouse>
            <TargetWarehouse>WS</TargetWarehouse>
            <CustomerPoNumber/>
        </Key>
        <ItemNumber>000003</ItemNumber>
    </Item>
    <Item>
        <Key>
            <SalesOrder>197591</SalesOrder>
            <SourceWarehouse>A4</SourceWarehouse>
            <TargetWarehouse>HI</TargetWarehouse>
            <CustomerPoNumber/>
        </Key>
        <ItemNumber>000004</ItemNumber>
    </Item>
    <Item>
        <Key>
            <SalesOrder>197592</SalesOrder>
            <SourceWarehouse>A4</SourceWarehouse>
            <TargetWarehouse>PV</TargetWarehouse>
            <CustomerPoNumber/>
        </Key>
        <ItemNumber>000005</ItemNumber>
    </Item>
    <Item>
        <Key>
            <SalesOrder>197593</SalesOrder>
            <SourceWarehouse>A4</SourceWarehouse>
            <TargetWarehouse>WS</TargetWarehouse>
            <CustomerPoNumber/>
        </Key>
        <ItemNumber>000006</ItemNumber>
    </Item>
    <StatusOfItems>
        <ItemsProcessed>000006</ItemsProcessed>
        <ItemsInvalid>000000</ItemsInvalid>
    </StatusOfItems>
</postsalesorderssct>

XSLT 2.0

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

    <xsl:template match="/postsalesorderssct/Item">
        <xsl:result-document href="{Key/SalesOrder}.xml">
            <Query xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORQRY.XSD">
                <Key>
                    <xsl:copy-of select="Key/SalesOrder"/>
                    <Invoice/>
                </Key>
                <Option>
                    <IncludeStockedLines>Y</IncludeStockedLines>
                    <IncludeNonStockedLines>Y</IncludeNonStockedLines>
                    <IncludeFreightLines>Y</IncludeFreightLines>
                    <IncludeMiscLines>Y</IncludeMiscLines>
                    <IncludeCommentLines>Y</IncludeCommentLines>
                    <IncludeCompletedLines>Y</IncludeCompletedLines>
                    <IncludeSerials>N</IncludeSerials>
                    <IncludeLots>Y</IncludeLots>
                    <IncludeBins>Y</IncludeBins>
                    <IncludeAttachedItems>N</IncludeAttachedItems>
                    <IncludeCustomForms>Y</IncludeCustomForms>
                    <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms>
                    <XslStylesheet/>
                </Option>
            </Query>        
        </xsl:result-document>      
    </xsl:template>

</xsl:stylesheet>

これにより、それぞれに個別のファイルが提供されますItem。ファイルの名前はSalesOrder.

いくつかの例...

197588.xml

<Query xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance"
       xsd:noNamespaceSchemaLocation="SORQRY.XSD">
   <Key>
      <SalesOrder>197588</SalesOrder>
      <Invoice/>
   </Key>
   <Option>
      <IncludeStockedLines>Y</IncludeStockedLines>
      <IncludeNonStockedLines>Y</IncludeNonStockedLines>
      <IncludeFreightLines>Y</IncludeFreightLines>
      <IncludeMiscLines>Y</IncludeMiscLines>
      <IncludeCommentLines>Y</IncludeCommentLines>
      <IncludeCompletedLines>Y</IncludeCompletedLines>
      <IncludeSerials>N</IncludeSerials>
      <IncludeLots>Y</IncludeLots>
      <IncludeBins>Y</IncludeBins>
      <IncludeAttachedItems>N</IncludeAttachedItems>
      <IncludeCustomForms>Y</IncludeCustomForms>
      <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms>
      <XslStylesheet/>
   </Option>
</Query>

197592.xml

<Query xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance"
       xsd:noNamespaceSchemaLocation="SORQRY.XSD">
   <Key>
      <SalesOrder>197592</SalesOrder>
      <Invoice/>
   </Key>
   <Option>
      <IncludeStockedLines>Y</IncludeStockedLines>
      <IncludeNonStockedLines>Y</IncludeNonStockedLines>
      <IncludeFreightLines>Y</IncludeFreightLines>
      <IncludeMiscLines>Y</IncludeMiscLines>
      <IncludeCommentLines>Y</IncludeCommentLines>
      <IncludeCompletedLines>Y</IncludeCompletedLines>
      <IncludeSerials>N</IncludeSerials>
      <IncludeLots>Y</IncludeLots>
      <IncludeBins>Y</IncludeBins>
      <IncludeAttachedItems>N</IncludeAttachedItems>
      <IncludeCustomForms>Y</IncludeCustomForms>
      <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms>
      <XslStylesheet/>
   </Option>
</Query>
于 2013-02-21T18:13:10.237 に答える
1

Daniel が示したように、XSLT 2.0 でこれを実現するのはかなり簡単です。残念ながら、私が知る限り、純粋な XSLT 1.0 では不可能ですが、もう少し頑張れば同じ結果を達成できます。

(決してこれを洗練されたソリューションと呼ぶつもりはありませんが、XSLT 2.0 を使用せずにこの問題を解決するために思いついた最初の方法です。)

どの XSLT プロセッサを使用しているのかわかりませんxsltproc

最初に、次のようなスタイルシートを使用して、すべての要素を含む XML ファイルを作成できます<Query>( で呼び出しますxsltproc allQuery.xsl input.xml)。

    <!-- allQuery.xsl -->

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance">
      <xsl:output method="xml" encoding="Windows-1252" omit-xml-declaration="yes" indent="yes"/>

      <xsl:template match="/">
        <Queries>
            <xsl:apply-templates select="postsalesorderssct/Item/Key/SalesOrder"/>
        </Queries>
      </xsl:template>

      <xsl:template match="SalesOrder">
        <xsl:variable name="id" select="."/>
          <Query xsd:noNamespaceSchemaLocation="SORQRY.XSD">
            <Key>
              <xsl:copy>
                <xsl:apply-templates/>
              </xsl:copy>
              <Invoice/>
            </Key>
            <Option>
                <IncludeStockedLines>Y</IncludeStockedLines>
                <IncludeNonStockedLines>Y</IncludeNonStockedLines>
                <IncludeFreightLines>Y</IncludeFreightLines>
                <IncludeMiscLines>Y</IncludeMiscLines>
                <IncludeCommentLines>Y</IncludeCommentLines>
                <IncludeCompletedLines>Y</IncludeCompletedLines>
                <IncludeSerials>N</IncludeSerials>
                <IncludeLots>Y</IncludeLots>
                <IncludeBins>Y</IncludeBins>
                <IncludeAttachedItems>N</IncludeAttachedItems>
                <IncludeCustomForms>Y</IncludeCustomForms>
                <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms>
                <XslStylesheet/>
            </Option>
          </Query>
      </xsl:template>
    </xsl:stylesheet>

次に、次のような別の単純なスタイルシートを作成できます。

<!-- extractQuery.xsl -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance">

  <xsl:output method="xml" encoding="Windows-1252" omit-xml-declaration="yes" indent="yes"/>

  <!-- The sales order number you pass in on the command line. -->
  <xsl:param name="salesOrderNo"/>

  <xsl:template match="/">
    <!--
    Only apply the <Query> element with a <SalesOrder> descendant that has 
    $salesOrderNo as its text content -- in the case of this example, 197593.
    --> 
    <xsl:apply-templates select="Queries/Query[descendant::SalesOrder[. = $salesOrderNo]]"/>
  </xsl:template>

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

</xsl:stylesheet>

このスタイルシートをxsltproc次のように使用して、取得する要素の SalesOrder 番号を<Query>パラメーターとしてスタイルシートに渡します。

xsltproc --stringparam salesOrderNo 197593 extractQuery.xsl output.xml

これにより、次の出力が生成されます。

<Query xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORQRY.XSD">
  <Key>
    <SalesOrder>197593</SalesOrder>
    <Invoice/>
  </Key>
  <Option>
    <IncludeStockedLines>Y</IncludeStockedLines>
    <IncludeNonStockedLines>Y</IncludeNonStockedLines>
    <IncludeFreightLines>Y</IncludeFreightLines>
    <IncludeMiscLines>Y</IncludeMiscLines>
    <IncludeCommentLines>Y</IncludeCommentLines>
    <IncludeCompletedLines>Y</IncludeCompletedLines>
    <IncludeSerials>N</IncludeSerials>
    <IncludeLots>Y</IncludeLots>
    <IncludeBins>Y</IncludeBins>
    <IncludeAttachedItems>N</IncludeAttachedItems>
    <IncludeCustomForms>Y</IncludeCustomForms>
    <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms>
    <XslStylesheet/>
  </Option>
</Query>

xsltproc次に、XML ファイルを作成する販売注文番号ごとに 1 回呼び出す必要があります。これを行う 1 つの方法は、さらに別のXSLT スタイルシートを作成することです。

<!-- getSalesOrderNos.xsl -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance">

  <xsl:output method="text" encoding="Windows-1252" omit-xml-declaration="yes"/>

  <xsl:template match="/">
    <xsl:apply-templates select="Queries/Query/Key/SalesOrder"/>
  </xsl:template>

  <xsl:template match="SalesOrder">
    <xsl:value-of select="."/><xsl:text>
</xsl:text>
  </xsl:template>

</xsl:stylesheet>

これにより、すべての販売注文番号の改行区切りリストが出力されます。次に、次のような Bash スクリプトで使用できます。

xsltproc getSalesOrderNos.xsl output.xml | xargs -L1 -I no xsltproc \
-o SalesOrder-no.xml --stringparam salesOrderNo no extractQuery.xsl output.xml

本質的に、これは のすべての販売注文番号のリストを出力し、番号ごとに 1 回output.xml実行し (extractQuery.xslパラメータとして に渡された番号を使用)、各変換の結果に対してextractQuery.xsl新しいファイル ( と呼ばれる) を作成します。SalesOrder-<ordernumber>.xml次のように:

<!-- SalesOrder-197588.xml -->

<Query xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORQRY.XSD">
  <Key>
    <SalesOrder>197588</SalesOrder>
    <Invoice/>
  </Key>
  <Option>
    <IncludeStockedLines>Y</IncludeStockedLines>
    <IncludeNonStockedLines>Y</IncludeNonStockedLines>
    <IncludeFreightLines>Y</IncludeFreightLines>
    <IncludeMiscLines>Y</IncludeMiscLines>
    <IncludeCommentLines>Y</IncludeCommentLines>
    <IncludeCompletedLines>Y</IncludeCompletedLines>
    <IncludeSerials>N</IncludeSerials>
    <IncludeLots>Y</IncludeLots>
    <IncludeBins>Y</IncludeBins>
    <IncludeAttachedItems>N</IncludeAttachedItems>
    <IncludeCustomForms>Y</IncludeCustomForms>
    <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms>
    <XslStylesheet/>
  </Option>
</Query>

おっしゃる通り、決して綺麗ではありません。アクセスできるツールによっては、このプロセスをかなり単純化できます (たとえば、XSLT 以外のものを使用して、販売注文番号のリストを抽出し、そこから処理を進めます)。

于 2013-02-21T21:39:33.203 に答える