无法在重复节点上进行xsl转换

时间:2017-08-31 16:32:33

标签: xml xslt

我有一些XML有1个销售订单,销售订单中有3个销售订单行。我之后的输出是一个表,如

|Line No | Description | Qty 
-----------------------------
|     1  | Product A   | 5
|     2  | Product B   | 10
|     3  | Product C   ! 7
-----------------------------

然而,我所取得的成就是

|Line No | Description | Qty 
-----------------------------
|     1  | Product A   | 5
|     1  | Product A   | 5
|     1  | Product A   | 5
-----------------------------

我完整地包含了我的XML输入和我的XSL(对不起,如果我提供了太多文本)

任何人都可以发现我的错误或建议前进的方向吗?

xml输入

<?xml version="1.0" encoding="UTF-8"?>
<SOQrySurcharge>
    <SalesOrders Language="05" Language2="EN" CssStyle="" DecFormat="1" DateFormat="01" Role="01" Version="6.1.083" OperatorPrimaryRole="   ">
    <Order>
      <CustomerPoNumber>7000654438</CustomerPoNumber>
      <SalesOrder>003411</SalesOrder>

    </Order>
  </SalesOrders>
  <SorDetail Language="05" Language2="EN" CssStyle="" DecFormat="1" DateFormat="01" Role="01" Version="6.1.025" OperatorPrimaryRole="   " xmlns:SALARE="SALARE" xmlns:SALSLS="SALSLS" xmlns:TBLART="TBLART" xmlns:SALBRN="SALBRN" xmlns:TBLCUR="TBLCUR">
    <SalesOrder>003411</SalesOrder>
    <CustomerName>Siemens</CustomerName>

    <HeaderText>
    </HeaderText>
    <SalesOrderLine>
      <Merchandise>
        <SalesOrderLine>   1</SalesOrderLine>
        <MStockCode>11</MStockCode>
        <MStockDes>Low Temp SG Surcharge</MStockDes>
        <MShipQty>       4.100</MShipQty>
        <MPrice>        121.72000</MPrice>
        <OrderLineValue>          499.05</OrderLineValue>

      </Merchandise>
    </SalesOrderLine>
    <SalesOrderLine>
      <Merchandise>
        <SalesOrderLine>   2</SalesOrderLine>
        <MStockCode>1</MStockCode>
        <MStockDes>Grey Iron Surcharge</MStockDes>
        <MShipQty>       0.264</MShipQty>
        <MPrice>        137.63000</MPrice>
        <OrderLineValue>           36.33</OrderLineValue>

      </Merchandise>
    </SalesOrderLine>
    <SalesOrderLine>
      <Merchandise>
        <SalesOrderLine>   3</SalesOrderLine>
       <MStockCode>13</MStockCode>
        <MStockDes>Ferritic SG + Mo Surcharge</MStockDes>
       <MShipQty>      15.155</MShipQty>
        <MPrice>        155.07000</MPrice>

      </Merchandise>
    </SalesOrderLine>
  </SorDetail>
</SOQrySurcharge>

xsl脚本

    <?xml version="1.0" encoding="Windows-1252" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes" />
    <xsl:template match="/">
        <html>
            <head>
                <title>Mestect Usage E-mail</title>
                <style>
            body {
            }

            h1 {
                text-align: left;
                color: #221076;
                font-size: 40px;
                font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif;
                font-weight: bold;
            }

            .def-container {
                 border: 2px solid black;
                margin: 0 0 3px 0;
                width: 70%;
                background-color: #FFA500;
            }

            .heading {
                display: inline;
                color: black;
                font-size: medium;
                font-family: Verdana, sans-serif;
                font-weight: bold;
            }

            .headingvalue {
                display: inline;
                color: black;
                font-size: medium;
                font-family: Verdana, sans-serif;
            }

                </style>
            </head>
            <body>
            <p> The following orders have been created by dataswitch in Syspro Company R</p>
                <h1>Auto created Material Surcharges</h1>
                <div class="def-container">
                    <div class="heading">Customer Purchase Order: </div>
                    <div class="headingvalue">
                        <xsl:value-of select="//CustomerPoNumber" />
                    </div>
                    <div class="heading">Customer: </div>
                    <div class="headingvalue">
                        <xsl:value-of select="//CustomerName" />
                    </div>
                    <div class="heading">Syspro Order: </div>
                    <div class="headingvalue">
                        <xsl:value-of select="//SalesOrder" />
                    </div>
                    <table border="1">
                    <tr>

                        <th>Surcharge Type</th>
                        <th>Surcharge Amount</th>
                        <th>Tonnes</th>
                        <th>Line Value</th>

                    </tr>

                     <xsl:for-each select="//Merchandise">

                        <tr>
                            <td>
                                <xsl:value-of select="//MStockDes" />
                            </td>
                            <td>
                                <xsl:value-of select="//MPrice" />
                            </td>
                            <td>
                                <xsl:value-of select="//MShipQty" />
                            </td>
                            <td>
                                <xsl:value-of select="//OrderLineValue" />
                            </td>
                        </tr>
                        </xsl:for-each>



                    </table>
                </div>

            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

最后,转换结果

<html>
  <head>
    <title>Mestect Usage E-mail</title>
    <style>
            body {
            }

            h1 {
                text-align: left;
                color: #221076;
                font-size: 40px;
                font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif;
                font-weight: bold;
            }

            .def-container {
                 border: 2px solid black;
                margin: 0 0 3px 0;
                width: 70%;
                background-color: #FFA500;
            }

            .heading {
                display: inline;
                color: black;
                font-size: medium;
                font-family: Verdana, sans-serif;
                font-weight: bold;
            }

            .headingvalue {
                display: inline;
                color: black;
                font-size: medium;
                font-family: Verdana, sans-serif;
            }

                </style>
  </head>
  <body>
    <p> The following orders have been created by dataswitch in Syspro Company R</p>
    <h1>Auto created Material Surcharges</h1>
    <div class="def-container">
      <div class="heading">Customer Purchase Order: </div>
      <div class="headingvalue">7000654438</div>
      <div class="heading">Customer: </div>
      <div class="headingvalue">Siemens</div>
      <div class="heading">Syspro Order: </div>
      <div class="headingvalue">003411</div>
      <table border="1">
        <tr>
          <th>Surcharge Type</th>
          <th>Surcharge Amount</th>
          <th>Tonnes</th>
          <th>Line Value</th>
        </tr>
        <tr>
          <td>Low Temp SG Surcharge</td>
          <td>        121.72000</td>
          <td>       4.100</td>
          <td>          499.05</td>
        </tr>
        <tr>
          <td>Low Temp SG Surcharge</td>
          <td>        121.72000</td>
          <td>       4.100</td>
          <td>          499.05</td>
        </tr>
        <tr>
          <td>Low Temp SG Surcharge</td>
          <td>        121.72000</td>
          <td>       4.100</td>
          <td>          499.05</td>
        </tr>
      </table>
    </div>
  </body>
</html>

3 个答案:

答案 0 :(得分:2)

您已自由使用//Merchandise这样的表达方式。前导//导致从输入文档的根进行绝对选择,而您需要从当前元素中进行相对选择。没有看到所有的细节,首先要做的是削减虚假领导&#34; //&#34;所有这些表达方式。

答案 1 :(得分:2)

考虑将<xsl:for-each>替换为与 Merchandise 节点匹配的其他模板。并使用normalize-space()删除节点文本值中的无关空格

更新了 XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:template match="/SOQrySurcharge">
    <html>
      <head>
        <title>Mestect Usage E-mail</title>
        <style>body { } h1 { text-align: left; color: #221076; font-size: 40px; font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-weight: bold; } .def-container { border: 2px solid black; margin: 0 0 3px 0; width: 70%; background-color: #FFA500; } .heading { display: inline; color: black; font-size: medium; font-family: Verdana, sans-serif; font-weight: bold; } .headingvalue { display: inline; color: black; font-size: medium; font-family: Verdana, sans-serif; }</style>
      </head>
      <body>
        <p>The following orders have been created by dataswitch in Syspro Company R</p>
        <h1>Auto created Material Surcharges</h1>
        <div class="def-container">
          <div class="heading">Customer Purchase Order:</div>
          <div class="headingvalue">
            <xsl:value-of select="SalesOrders/Order/CustomerPoNumber" />
          </div>
          <div class="heading">Customer:</div>
          <div class="headingvalue">
            <xsl:value-of select="SorDetail/CustomerName" />
          </div>
          <div class="heading">Syspro Order:</div>
          <div class="headingvalue">
            <xsl:value-of select="SalesOrders/Order/SalesOrder" />
          </div>
          <table border="1">
            <tr>
              <th>Surcharge Type</th>
              <th>Surcharge Amount</th>
              <th>Tonnes</th>
              <th>Line Value</th>
            </tr>
            <xsl:apply-templates select="SorDetail/SalesOrderLine" />
          </table>
        </div>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="Merchandise">
    <tr>
      <td>
        <xsl:value-of select="normalize-space(MStockDes)" />
      </td>
      <td>
        <xsl:value-of select="format-number(normalize-space(MPrice),'#0.##')" />
      </td>
      <td>
        <xsl:value-of select="format-number(normalize-space(MShipQty),'#0.##')" />
      </td>
      <td>
        <xsl:if test="OrderLineValue">
          <xsl:value-of select="format-number(normalize-space(OrderLineValue),'#.##')" />
        </xsl:if>
      </td>
    </tr>
  </xsl:template>

</xsl:stylesheet>

输出 XML

<html>
  <head>
    <title>Mestect Usage E-mail</title>
    <style>body { } h1 { text-align: left; color: #221076; font-size: 40px; font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-weight: bold; } .def-container { border: 2px solid black; margin: 0 0 3px 0; width: 70%; background-color: #FFA500; } .heading { display: inline; color: black; font-size: medium; font-family: Verdana, sans-serif; font-weight: bold; } .headingvalue { display: inline; color: black; font-size: medium; font-family: Verdana, sans-serif; }</style>
  </head>
  <body>
    <p>The following orders have been created by dataswitch in Syspro Company R</p>
    <h1>Auto created Material Surcharges</h1>
    <div class="def-container">
      <div class="heading">Customer Purchase Order:</div>
      <div class="headingvalue">7000654438</div>
      <div class="heading">Customer:</div>
      <div class="headingvalue">Siemens</div>
      <div class="heading">Syspro Order:</div>
      <div class="headingvalue">003411</div>
      <table border="1">
        <tr>
          <th>Surcharge Type</th>
          <th>Surcharge Amount</th>
          <th>Tonnes</th>
          <th>Line Value</th>
        </tr>
        <tr>
          <td>Low Temp SG Surcharge</td>
          <td>121.72</td>
          <td>4.1</td>
          <td>499.05</td>
        </tr>
        <tr>
          <td>Grey Iron Surcharge</td>
          <td>137.63</td>
          <td>0.26</td>
          <td>36.33</td>
        </tr>
        <tr>
          <td>Ferritic SG + Mo Surcharge</td>
          <td>155.07</td>
          <td>15.16</td>
          <td />
        </tr>
      </table>
    </div>
  </body>
</html>

答案 2 :(得分:0)

xpath查询中的//返回节点发送。 <xsl:value-of只关注第一个元素。发生了什么事情是你按名称返回每个Merchandise的第一个元素。您需要将xpath查询更改为相对,如下所示。

<xsl:for-each select="//Merchandise">
    <tr>
        <td>
            <xsl:value-of select="./MStockDes" />
        </td>
        <td>
            <xsl:value-of select="./MPrice" />
        </td>