0

很明显,我对 XML 和 XSLT 的了解相当有限。请有人可以帮助我提供一个翻译文件,该文件将允许传递以下 XML 中的每个 ItemNumber/Sales Order,以便为每个项目生成第二个 XML。换句话说,我需要生成多个输出 xml(每个销售订单一个)。目前,我只为初始 xml 上的最后一个行项目/销售订单获得一个输出 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 所需的输出。换句话说,我需要为每个销售订单号生成其中一个:

<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.

您可以首先使用这样的样式表来创建一个包含所有<Query>元素的 XML 文件(用 调用它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 文件的每个销售订单号调用一次。一种方法是创建另一个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

本质上,这将打印出所有销售订单编号的列表,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>

As I said, it's not pretty by any means. Depending on what tools you have access to, you might simplify this process quite a bit (e.g. use something else than XSLT to extract the list of sales order numbers and proceed from there).

于 2013-02-21T21:39:33.203 回答