XML转换的行为不符合预期。我需要循环吗?

时间:2016-04-28 13:15:40

标签: xml ms-access xslt

我在给定时间段内以订单的形式从我的网站获取XML数据。

<?xml version="1.0"?>
<WEB_ORDERS>
  <WEB_ORDER>
    <ORDER>
      <ORDER_ID>1234</ORDER_ID>
      <ORDER_REFERENCE>WEB3395</ORDER_REFERENCE>
      <DELIVERY_METHOD>UPS Access Point (FREE) (pay by card only)</DELIVERY_METHOD>
      <GIFTWRAP_TOTAL_INC>0</GIFTWRAP_TOTAL_INC>
      <GIFTWRAP_TOTAL_NET>0</GIFTWRAP_TOTAL_NET>
      <GIFTWRAP_TOTAL_VAT>0</GIFTWRAP_TOTAL_VAT>
      <NUMBER_PRODUCTS>1</NUMBER_PRODUCTS>
    </ORDER>
    <CUSTOMER>
      <CUSTOMER_ID>3392</CUSTOMER_ID>
      <BILLING_COMPANY_NAME></BILLING_COMPANY_NAME>
      <BILLING_TITLE>MR</BILLING_TITLE>
      <BILLING_FIRSTNAME>C3</BILLING_FIRSTNAME>
      <BILLING_LASTNAME>PO</BILLING_LASTNAME>
      <Customer_Data>data here</Customer_Data>
    </CUSTOMER>
  </WEB_ORDER>
  <WEB_ORDER>
    <ORDER>
      <ORDER_ID>3396</ORDER_ID>
      <ORDER_REFERENCE>WEB3396</ORDER_REFERENCE>
      <DELIVERY_METHOD>UPS Access Point (FREE) (pay by card only)</DELIVERY_METHOD>
      <GIFTWRAP_TOTAL_INC>0</GIFTWRAP_TOTAL_INC>
      <GIFTWRAP_TOTAL_NET>0</GIFTWRAP_TOTAL_NET>
      <GIFTWRAP_TOTAL_VAT>0</GIFTWRAP_TOTAL_VAT>
      <NUMBER_PRODUCTS>2</NUMBER_PRODUCTS>
    </ORDER>
    <CUSTOMER>
      <CUSTOMER_ID>2584</CUSTOMER_ID>
      <BILLING_COMPANY_NAME></BILLING_COMPANY_NAME>
      <BILLING_TITLE>MR</BILLING_TITLE>
      <BILLING_FIRSTNAME>R2</BILLING_FIRSTNAME>
      <BILLING_LASTNAME>D2</BILLING_LASTNAME>
      <Customer_Data>data here</Customer_Data>
    </CUSTOMER>
  </WEB_ORDER>

</WEB_ORDERS>

将这些数据导入访问后,数据被分成了它的子节点,因此我获得了许多表。除了某些表之间没有链接之外,这很好。

例如,

订单包含没有客户链接。所以我了解了XSLT。 然后编写一个将CUSTOMER_ID插入<ORDERS>。它适用于具有单个订单的文件。但是某些文件(如上面的XML)中有多个订单,因此它只会复制原始客户编号(在这种情况下为1234)并将其应用于所有订单。我真的不确定如何循环,但每个<WEB_ORDER>执行我的转换,然后循环到下一个<WEB_ORDER>

这是我为单个订单文件工作的XSLT。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <WEB_ORDER>
            <xsl:apply-templates select="@*|node()"/>
        </WEB_ORDER>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="WEB_ORDER">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:template>

    <xsl:template match="ORDER">
        <ORDER>
            <CUSTOMER_ID><xsl:value-of select="/WEB_ORDERS/WEB_ORDER/CUSTOMER/CUSTOMER_ID"/></CUSTOMER_ID>
            <xsl:apply-templates select="@*|node()"/>
        </ORDER>
    </xsl:template>

</xsl:stylesheet>

因此,当我在XML上运行此转换时,我会在每个订单中重复第一个web_order客户ID

    <?xml version="1.0"?>
    <WEB_ORDERS>
      <WEB_ORDER>
        <ORDER>
          <CUSTOMER_ID>3392</CUSTOMER_ID>
          <ORDER_ID>1234</ORDER_ID>
          <ORDER_REFERENCE>WEB3395</ORDER_REFERENCE>
          <DELIVERY_METHOD>UPS Access Point (FREE) (pay by card only)</DELIVERY_METHOD>
          <GIFTWRAP_TOTAL_INC>0</GIFTWRAP_TOTAL_INC>
          <GIFTWRAP_TOTAL_NET>0</GIFTWRAP_TOTAL_NET>
          <GIFTWRAP_TOTAL_VAT>0</GIFTWRAP_TOTAL_VAT>
          <NUMBER_PRODUCTS>1</NUMBER_PRODUCTS>
        </ORDER>
        <CUSTOMER>
          <CUSTOMER_ID>3392</CUSTOMER_ID>
          <BILLING_COMPANY_NAME></BILLING_COMPANY_NAME>
          <BILLING_TITLE>MR</BILLING_TITLE>
          <BILLING_FIRSTNAME>C3</BILLING_FIRSTNAME>
          <BILLING_LASTNAME>PO</BILLING_LASTNAME>
          <Customer_Data>data here</Customer_Data>
        </CUSTOMER>
      </WEB_ORDER>
      <WEB_ORDER>
        <ORDER>
          <CUSTOMER_ID>3392</CUSTOMER_ID>
          <ORDER_ID>3396</ORDER_ID>
          <ORDER_REFERENCE>WEB3396</ORDER_REFERENCE>
          <DELIVERY_METHOD>UPS Access Point (FREE) (pay by card only)</DELIVERY_METHOD>
          <GIFTWRAP_TOTAL_INC>0</GIFTWRAP_TOTAL_INC>
          <GIFTWRAP_TOTAL_NET>0</GIFTWRAP_TOTAL_NET>
          <GIFTWRAP_TOTAL_VAT>0</GIFTWRAP_TOTAL_VAT>
          <NUMBER_PRODUCTS>2</NUMBER_PRODUCTS>
        </ORDER>
        <CUSTOMER>
          <CUSTOMER_ID>2584</CUSTOMER_ID>
          <BILLING_COMPANY_NAME></BILLING_COMPANY_NAME>
          <BILLING_TITLE>MR</BILLING_TITLE>
          <BILLING_FIRSTNAME>R2</BILLING_FIRSTNAME>
          <BILLING_LASTNAME>D2</BILLING_LASTNAME>
          <Customer_Data>data here</Customer_Data>
        </CUSTOMER>
      </WEB_ORDER>

    </WEB_ORDERS>

我想要获得的是订单节点中的web_order的客户ID

<?xml version="1.0"?>
<WEB_ORDERS>
  <WEB_ORDER>
    <ORDER>
      <CUSTOMER_ID>3392</CUSTOMER_ID>
      <ORDER_ID>1234</ORDER_ID>
      <ORDER_REFERENCE>WEB3395</ORDER_REFERENCE>
      <DELIVERY_METHOD>UPS Access Point (FREE) (pay by card only)</DELIVERY_METHOD>
      <GIFTWRAP_TOTAL_INC>0</GIFTWRAP_TOTAL_INC>
      <GIFTWRAP_TOTAL_NET>0</GIFTWRAP_TOTAL_NET>
      <GIFTWRAP_TOTAL_VAT>0</GIFTWRAP_TOTAL_VAT>
      <NUMBER_PRODUCTS>1</NUMBER_PRODUCTS>
    </ORDER>
    <CUSTOMER>
      <CUSTOMER_ID>3392</CUSTOMER_ID>
      <BILLING_COMPANY_NAME></BILLING_COMPANY_NAME>
      <BILLING_TITLE>MR</BILLING_TITLE>
      <BILLING_FIRSTNAME>C3</BILLING_FIRSTNAME>
      <BILLING_LASTNAME>PO</BILLING_LASTNAME>
      <Customer_Data>data here</Customer_Data>
    </CUSTOMER>
  </WEB_ORDER>
  <WEB_ORDER>
    <ORDER>
      <CUSTOMER_ID>2584</CUSTOMER_ID>
      <ORDER_ID>3396</ORDER_ID>
      <ORDER_REFERENCE>WEB3396</ORDER_REFERENCE>
      <DELIVERY_METHOD>UPS Access Point (FREE) (pay by card only)</DELIVERY_METHOD>
      <GIFTWRAP_TOTAL_INC>0</GIFTWRAP_TOTAL_INC>
      <GIFTWRAP_TOTAL_NET>0</GIFTWRAP_TOTAL_NET>
      <GIFTWRAP_TOTAL_VAT>0</GIFTWRAP_TOTAL_VAT>
      <NUMBER_PRODUCTS>2</NUMBER_PRODUCTS>
    </ORDER>
    <CUSTOMER>
      <CUSTOMER_ID>2584</CUSTOMER_ID>
      <BILLING_COMPANY_NAME></BILLING_COMPANY_NAME>
      <BILLING_TITLE>MR</BILLING_TITLE>
      <BILLING_FIRSTNAME>R2</BILLING_FIRSTNAME>
      <BILLING_LASTNAME>D2</BILLING_LASTNAME>
      <Customer_Data>data here</Customer_Data>
    </CUSTOMER>
  </WEB_ORDER>

</WEB_ORDERS>

1 个答案:

答案 0 :(得分:2)

问题在于这一行,因为它获取XML中的第一个CUSTOMER_ID节点,无论您使用的是什么ORDER

<xsl:value-of select="/WEB_ORDERS/WEB_ORDER/CUSTOMER/CUSTOMER_ID"/>

您需要将其更改为此,以便它获取当前CUSTOMER节点的同一父节点的ORDER节点。 (..获取当前节点的父节点。)

<xsl:value-of select="../CUSTOMER/CUSTOMER_ID"/>

尝试使用此模板代替当前的

<xsl:template match="ORDER">
    <ORDER>
        <xsl:apply-templates select="@*"/>
        <CUSTOMER_ID><xsl:value-of select="../CUSTOMER/CUSTOMER_ID"/></CUSTOMER_ID>
        <xsl:apply-templates select="node()"/>
    </ORDER>
</xsl:template>

请注意我如何分割@*node()的选择,因为必须在任何子节点之前将属性添加到父元素。

但是在回答你的问题时,不,你不需要循环。您的模板方法非常适合。