很明显,我对XML和XSLT的了解相当有限。请有人帮我一个翻译文件,该文件允许传递以下XML中的每个ItemNumber / Sales Order,以便为每个项目生成第二个XML。换句话说,我需要生成多个输出xmls(每个销售订单一个)。目前我只为初始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>
在期待中感谢你。
答案 0 :(得分: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>
答案 1 :(得分:1)
正如丹尼尔所展示的那样,使用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
一起使用,将要获取的<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>
然后,您需要为要为其创建XML文件的每个销售订单号调用xsltproc
一次。一种方法是创建另一个 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
一次 - 将参考号作为参数传递给{{1} - 并为每次转换的结果创建一个新文件(称为extractQuery.xsl
)。如:
SalesOrder-<ordernumber>.xml
正如我所说,无论如何都不是很好。根据您可以访问的工具,您可以稍微简化此过程(例如,使用除XSLT之外的其他内容来提取销售订单编号列表并从那里继续)。