我们有一组订单作为单个XML。其中一条线是强制性的,称为主线,每个订单只有一条,并且在标题级别没有任何重复。还有两种不是强制性的行类型,但可以为每个订单重复。以下是输入XML示例,输出只是行的集合。
包括主线,所有可选线和所有自定义线在内的所有线都需要根据每个订单映射到目标上的相同元素。
<orderDetails>
<data>
<order>
<poNumber>1234</poNumber>
<storeNumber>35</storeNumber>
<itemNumber>1895550045</itemNumber>
<mainLine>
<referenceNumber>I1</referenceNumber>
<basicInstallCostAmount>100</basicInstallCostAmount>
<basicInstallQuantity>12</basicInstallQuantity>
</mainLine>
<optionalLines>
<optionalLine>
<referenceNumber>OP10</referenceNumber>
<duoiCode>EA</duoiCode>
<orderQuantity>15</orderQuantity>
<orderRetailAmount>200</orderRetailAmount>
</optionalLine>
<optionalLine>
<referenceNumber>OP105</referenceNumber>
<duoiCode>EA</duoiCode>
<orderQuantity>23</orderQuantity>
<orderRetailAmount>655</orderRetailAmount>
</optionalLine>
</optionalLines>
<customLines>
<customLine>
<referenceNumber>C100</referenceNumber>
<duoiCode>EA</duoiCode>
<orderQuantity>123</orderQuantity>
<orderRetailAmount>12300</orderRetailAmount>
</customLine>
<customLine>
<referenceNumber>C1337</referenceNumber>
<duoiCode>EA</duoiCode>
<orderQuantity>357</orderQuantity>
<orderRetailAmount>143</orderRetailAmount>
</customLine>
</customLines>
</order>
<order>
<poNumber>5678</poNumber>
<storeNumber>52</storeNumber>
<itemNumber>0005554433</itemNumber>
<mainLine>
<referenceNumber>I21</referenceNumber>
<basicInstallCostAmount>3000</basicInstallCostAmount>
<basicInstallQuantity>35</basicInstallQuantity>
</mainLine>
<optionalLines>
<optionalLine>
<referenceNumber>OP134</referenceNumber>
<duoiCode>EA</duoiCode>
<orderQuantity>1500</orderQuantity>
<orderRetailAmount>350000</orderRetailAmount>
</optionalLine>
</optionalLines>
<customLines>
<customLine>
<referenceNumber>C140</referenceNumber>
<duoiCode>EA</duoiCode>
<orderQuantity>13</orderQuantity>
<orderRetailAmount>100</orderRetailAmount>
</customLine>
</customLines>
</order>
</data>
</orderDetails>
预期产出 -
<PoHeadersCollection>
<PoHeaders>
<poNumber>1234</poNumber>
<storeNumber>35</storeNumber>
<itemNumber>1895550045</itemNumber>
<PoLinesCollection>
<PoLines>
<partNumber>I1</partNumber>
<Quantity>12</Quantity>
<installType>Basic</installType>
<lineAmount>100</lineAmount>
</PoLines>
<PoLines>
<partNumber>OP10</partNumber>
<Uom>EA</Uom>
<Quantity>15</Quantity>
<installType>Optional</installType>
<lineAmount>200</lineAmount>
</PoLines>
<PoLines>
<partNumber>OP105</partNumber>
<Uom>EA</Uom>
<Quantity>23</Quantity>
<installType>Optional</installType>
<lineAmount>655</lineAmount>
</PoLines>
<PoLines>
<partNumber>C100</partNumber>
<Uom>EA</Uom>
<Quantity>123</Quantity>
<installType>Custom</installType>
<lineAmount>12300</lineAmount>
</PoLines>
<PoLines>
<partNumber>C1337</partNumber>
<Uom>EA</Uom>
<Quantity>357</Quantity>
<installType>Custom</installType>
<lineAmount>143</lineAmount>
</PoLines>
</PoLinesCollection>
</PoHeaders>
<PoHeaders>
<poNumber>5678</poNumber>
<storeNumber>52</storeNumber>
<itemNumber>0005554433</itemNumber>
<PoLinesCollection>
<PoLines>
<partNumber>I21</partNumber>
<Quantity>35</Quantity>
<installType>Basic</installType>
<lineAmount>3000</lineAmount>
</PoLines>
<PoLines>
<partNumber>OP134</partNumber>
<Uom>EA</Uom>
<Quantity>1500</Quantity>
<installType>Optional</installType>
<lineAmount>350000</lineAmount>
</PoLines>
<PoLines>
<partNumber>C140</partNumber>
<Uom>EA</Uom>
<Quantity>13</Quantity>
<installType>Custom</installType>
<lineAmount>100</lineAmount>
</PoLines>
</PoLinesCollection>
</PoHeaders>
</PoHeadersCollection>
我尝试使用for-each并在循环内尝试为其余的线类型应用模板,但它重复所有节点。
下面是我试图使用的XSLT,并且缺少如何在for循环中单独应用当前节点的模板 -
<xsl:stylesheet version="1.0">
<xsl:template match="/">
<PoHeadersCollection>
<xsl:for-each select="/orderDetails/data/order">
<ThdIconxPoHeaders>
<poNumber>
<xsl:value-of select="poNumber"/>
</poNumber>
<storeNumber>
<xsl:value-of select="storeNumber"/>
</storeNumber>
<itemNumber>
<xsl:value-of select="itemNumber"/>
</itemNumber>
<PoLinesCollection>
<PoLines>
<partNumber>
<xsl:value-of select="mainLine/referenceNumber"/>
</partNumber>
<Uom>
<xsl:value-of select="mainLine/duoiCode"/>
</Uom>
<Quantity>
<xsl:value-of select="mainLine/basicInstallQuantity"/>
</Quantity>
<installType>
<xsl:text disable-output-escaping="no">Basic</xsl:text>
</installType>
<lineAmount>
<xsl:value-of select="mainLine/basicInstallCostAmount"/>
</lineAmount>
</PoLines>
<xsl:apply-templates select="//*[local-name()='optionalLine']"/>
<xsl:apply-templates select="//*[local-name()='customLine']"/>
</PoLinesCollection>
</PoHeaders>
</xsl:for-each>
</PoHeadersCollection>
</xsl:template>
<xsl:template match="*[local-name()='optionalLine']">
<PoLines>
<partNumber>
<xsl:value-of select="referenceNumber"/>
</partNumber>
<Uom>
<xsl:value-of select="duoiCode"/>
</Uom>
<Quantity>
<xsl:value-of select="orderQuantity"/>
</Quantity>
<installType>
<xsl:text disable-output-escaping="no">Optional</xsl:text>
</installType>
</PoLines>
</xsl:template>
<xsl:template match="*[local-name()='customLine']">
<PoLines>
<partNumber>
<xsl:value-of select="referenceNumber"/>
</partNumber>
<Uom>
<xsl:value-of select="duoiCode"/>
</Uom>
<Quantity>
<xsl:value-of select="orderQuantity"/>
</Quantity>
<installType>
<xsl:text disable-output-escaping="no">Custom</xsl:text>
</installType>
</PoLines>
</xsl:template>
</xsl:stylesheet>
请建议。
提前致谢, 集塔
答案 0 :(得分:0)
您的问题是绝对路径,例如
<xsl:apply-templates select="//*[local-name()='optionalLine']"/>
每次都会从文档中的每个顺序中选择相应类型的所有行。相反,您需要使用 relative 路径而不使用前导斜杠
<xsl:apply-templates select="optionalLines/optionalLine"/>
只查找您当前正在查看的订单中的那些行。
就我个人而言,我会将整块大块分解成较小的模板,以捕捉不同类型线条之间的共性。
<xsl:template match="/">
<PoHeadersCollection>
<xsl:apply-templates select="orderDetails/data/order" />
</PoHeadersCollection>
</xsl:template>
<xsl:template match="order">
<PoHeaders>
<xsl:copy-of select="poNumber | storeNumber | itemNumber" />
<PoLinesCollection>
<!-- process all the different types of line in one go -->
<xsl:apply-templates select="mainLine
| optionalLines/optionalLine
| customLines/customLine" />
</PoLinesCollection>
</PoHeaders>
</xsl:template>
<xsl:template match="mainLine | optionalLine | customLine">
<PoLines>
<xsl:apply-templates select="referenceNumber"/>
<xsl:apply-templates select="duoiCode"/><!-- won't exist for main line -->
<xsl:apply-templates select="basicInstallQuantity | orderQuantity"/>
<xsl:apply-templates select="." mode="lineType" />
<xsl:apply-templates select="basicInstallCostAmount | orderRetailAmount"/>
</PoLines>
</xsl:template>
<xsl:template match="referenceNumber">
<partNumber><xsl:apply-templates/></partNumber>
</xsl:template>
<xsl:template match="duoiCode">
<Uom><xsl:apply-templates/></Uom>
</xsl:template>
<!-- etc. for other elements -->
并使用特殊模板模式来处理installType
:
<xsl:template match="mainLine" mode="lineType">
<installType>Basic</installType>
</xsl:template>
<xsl:template match="optionalLine" mode="lineType">
<installType>Optional</installType>
</xsl:template>
<xsl:template match="customLine" mode="lineType">
<installType>Custom</installType>
</xsl:template>