2013-02-21 35 views
0

可能很明顯,我對XML和XSLT的瞭解相當有限。請有人幫助我提供一個翻譯文件,該文件將允許下面XML中的每個ItemNumber/Sales Order傳遞,以便爲每個項目生成第二個XML。換句話說,我需要生成多個輸出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> 

下面是每個上的ItemNumbers所需的輸出最初的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> 

感謝您的期望。

+0

您的XSLT與您的輸入XML不匹配。例如,在您的XSLT中,您使用'postsororderstatus/Item/Order',但在輸入XML中,根是'',因此在那裏沒有匹配。你也循環遍歷每個'',但是這個元素也不在你的輸入XML中。當我看到所需的輸出時,這也不符合。所以你想要什麼?或者請糾正你的問題! – 2013-02-21 09:34:20

+0

您正在使用哪個版本的XSLT?在XSLT 1.0中,現在有一種方法可以在不使用擴展元素的情況下執行此操作(如果您有權訪問exslt,則可以使用)。在XSLT 2.0中,您可以使用生成多個輸出文件。 – 2013-02-21 10:17:05

+0

我的歉意標記我打開了多個文件並複製了錯誤的文件。我會相應地調整問題。 – 2013-02-21 14:55:11

回答

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> 
+0

嗨丹尼爾。可悲的是我不能使用xslt 2.0。任何想法如何使用版本1實現這一目標? – 2013-02-21 20:12:05

+0

@DevonTrew - 如果你的處理器支持exslt,你可以使用'exsl:document'。如果XSLT 2.0或EXSL不可用,請參閱http://www.exslt.org/exsl/elements/document/index.html – 2013-02-21 21:16:40

1

用XSLT 2.0實現,這是非常簡單的,因爲丹尼爾證明。不幸的是,使用純粹的XSLT 1.0,就我所知,這是不可能的,但如果你願意努力工作,你可以達到同樣的結果。

(我不會把這個以任何方式一個很好的解決方案,但它是我能想出的沒有XSLT 2.0解決這個問題的第一種方法。)

我不知道哪個XSLT處理器您我正在使用,所以我會用xsltproc來演示。

你可以先用這樣的樣式表來創建一個包含所有<Query>元素(與xsltproc allQuery.xsl input.xml稱呼它)的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,將想要獲取的<Query>元素的SalesOrder編號傳遞給樣式表:

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> 

正如我所說,這是不漂亮的任何手段。根據您有權訪問的工具,您可能會稍微簡化此過程(例如,使用除XSLT之外的其他內容來提取銷售訂單編號列表並從此處繼續)。

+0

+1以獲得可行的解決方案。 – 2013-02-21 22:33:48