XML转换合并多个节点和外键

时间:2015-10-21 16:56:37

标签: xml ms-access xslt

我在转换此XML以导入Access时遇到问题。我需要将FA,Prospect和发货信息节点中的所有内容都归入一个请求,并将OrderID作为主键。但是,我希望将程序选择和营销材料放在单独的表中,并将OrderID作为外键。 用户(FA)为一个潜在客户发出一个请求(由OrderID标识),但每个请求可以有多个程序选择和营销材料请求。

以下是我正在使用的XML:

<?xml version="1.0" encoding="UTF-8"?>
<Requests>
  <Request>
    <Request_Type><![CDATA[Wealth Onshore]]></Request_Type>
    <Employee_ID><![CDATA[334668]]></Employee_ID>
    <FA>
      <Division><![CDATA[IFS]]></Division>
      <Name>
        <Advisor_firstname><![CDATA[Steven]]></Advisor_firstname>
        <Advisor_lastname><![CDATA[Doe]]></Advisor_lastname>
      </Name>
      <Address>
        <Advisor_Address><![CDATA[9999 Ross Ave]]></Advisor_Address>
        <Advisor_Address2><![CDATA[suite 5200]]></Advisor_Address2>
        <Advisor_Address3><![CDATA[null]]></Advisor_Address3>
        <Advisor_Address4 />
        <Advisor_City><![CDATA[New York]]></Advisor_City>
        <Advisor_State><![CDATA[TX]]></Advisor_State>
        <Advisor_Zip><![CDATA[99999]]></Advisor_Zip>
        <Advisor_Country />
      </Address>
      <Company_Name><![CDATA[Tyco]]></Company_Name>
      <Advisor_Phone><![CDATA[(333) 721-6457]]></Advisor_Phone>
      <Advisor_Email><![CDATA[jon@company.com]]></Advisor_Email>
      <Advisor_Business_Name><![CDATA[null]]></Advisor_Business_Name>
      <Manager_Name><![CDATA[Bill]]></Manager_Name>
    </FA>
    <Prospect>
      <Subscription_Type><![CDATA[Existing Investor]]></Subscription_Type>
      <Prospect_Firstname><![CDATA[A big trust]]></Prospect_Firstname>
      <Prospect_Lastname />
      <Address>
        <Prospect_Address><![CDATA[900 Street]]></Prospect_Address>
        <Prospect_Address2><![CDATA[null]]></Prospect_Address2>
        <Prospect_Address3><![CDATA[null]]></Prospect_Address3>
        <Prospect_City><![CDATA[Great FALLS]]></Prospect_City>
        <Prospect_State><![CDATA[TX]]></Prospect_State>
        <Prospect_Zip><![CDATA[99999]]></Prospect_Zip>
        <Prospect_Country />
      </Address>
      <Prospect_Investor_Type><![CDATA[Family Entity]]></Prospect_Investor_Type>
      <Prospect_Employee_Investor><![CDATA[N]]></Prospect_Employee_Investor>
    </Prospect>
    <ProgramSelection>
      <Interest><![CDATA[I Interest]]></Interest>
      <Program><![CDATA[Hedge Funds & Private Capital (Monthly Investment) Managed Futures & Commodities Real Estate]]></Program>
      <Number_Kits><![CDATA[0]]></Number_Kits>
      <Type_Kit />
    </ProgramSelection>
    <MarketingMaterial>
      <ExecutiveSummary />
      <FactSheet>
        <Program><![CDATA[Equity Hedge Legends]]></Program>
        <Program><![CDATA[Pinehurst]]></Program>
      </FactSheet>
      <ProductProfile>
        <Program><![CDATA[Equity Hedge Legends]]></Program>
        <Program><![CDATA[Pinehurst]]></Program>
      </ProductProfile>
      <Presentation>
        <Program><![CDATA[Equity Hedge Legends]]></Program>
        <Program><![CDATA[Pinehurst]]></Program>
      </Presentation>
      <Overview />
    </MarketingMaterial>
    <ShippingInformation>
      <Shipping_Method><![CDATA[Online Delivery]]></Shipping_Method>
      <CO_SUB_RC><![CDATA[0079486]]></CO_SUB_RC>
      <Ship_To><![CDATA[Online Delivery to Advisor]]></Ship_To>
      <Other_Name><![CDATA[null]]></Other_Name>
      <Other_Address><![CDATA[null]]></Other_Address>
      <Other_Address2><![CDATA[null]]></Other_Address2>
      <Other_City><![CDATA[null]]></Other_City>
      <Other_State><![CDATA[null]]></Other_State>
      <Other_Zip><![CDATA[null]]></Other_Zip>
      <Other_Country />
      <Prospect_Email />
      <Special_Instructions><![CDATA[null]]></Special_Instructions>
    </ShippingInformation>
    <OrderID><![CDATA[82281]]></OrderID>
    <OrderDateTime><![CDATA[10/20/2015 15:17:04]]></OrderDateTime>
    <OrderComments><![CDATA[null]]></OrderComments>
    <ApprovalStatus><![CDATA[Approved]]></ApprovalStatus>
  </Request>
</Requests>

以下是我正在使用或正在尝试使用的转换......

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


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

    <xsl:template match="Name">
    <Name>
        <OrderID><xsl:value-of select="../OrderID"/></OrderID>
        <xsl:apply-templates select="@*|node()"/>
    </Name>
    </xsl:template>
    <xsl:template match="Address">
    <Address>
        <OrderID><xsl:value-of select="../OrderID"/></OrderID>
        <xsl:apply-templates select="@*|node()"/>
    </Address>
    </xsl:template>
    <xsl:template match="FA">
    <FA>
        <OrderID><xsl:value-of select="../OrderID"/></OrderID>
        <xsl:apply-templates select="@*|node()"/>
    </FA>
    </xsl:template>
    <xsl:template match="Prospect">
    <Prospect>
        <OrderID><xsl:value-of select="../OrderID"/></OrderID>
        <xsl:apply-templates select="@*|node()"/>
    </Prospect>
    </xsl:template>
    <xsl:template match="ProgramSelection">
    <ProgramSelection>
        <OrderID><xsl:value-of select="../OrderID"/></OrderID>
        <xsl:apply-templates select="@*|node()"/>
    </ProgramSelection>
    </xsl:template>
    <xsl:template match="FactSheet">
    <FactSheet>
        <OrderID><xsl:value-of select="../../OrderID"/></OrderID>
        <xsl:apply-templates select="@*|node()"/>
    </FactSheet>
    </xsl:template>
    <xsl:template match="ProductProfile">
    <ProductProfile>
        <OrderID><xsl:value-of select="../../OrderID"/></OrderID>
        <xsl:apply-templates select="@*|node()"/>
    </ProductProfile>
 </xsl:template>
    <xsl:template match="Presentation">
    <Presentation>
        <OrderID><xsl:value-of select="../../OrderID"/></OrderID>
        <xsl:apply-templates select="@*|node()"/>
    </Presentation>
    </xsl:template>
    <xsl:template match="MarketingMaterial">
    <MarketingMaterial>
        <OrderID><xsl:value-of select="../OrderID"/></OrderID>
        <xsl:apply-templates select="@*|node()"/>
    </MarketingMaterial>
    </xsl:template>
    <xsl:template match="ShippingInformation">
    <ShippingInformation>
        <OrderID><xsl:value-of select="../OrderID"/></OrderID>
        <xsl:apply-templates select="@*|node()"/>
    </ShippingInformation>
    </xsl:template>
    <xsl:template match="ExecutiveSummary">
    <ExecutiveSummary>
        <OrderID><xsl:value-of select="../../OrderID"/></OrderID>
        <xsl:apply-templates select="@*|node()"/>
    </ExecutiveSummary>
</xsl:template>


    </xsl:stylesheet>

编辑:我寻找营销材料和程序选择节点的结果将是这样的。

    <ProgramSelection>
        <Selection>
            <Interest>I Interest</Interest>
            <Program>FundChoice1</Program>
            <OrderID>19827</OrderiD>
        </Selection>
        <Selection>
            <Interest>I Interest</Interest>
            <Program>Fund Choice2</Program>
            <OrderID>19827</OrderiD>
        </Selection>    
    </ProgramSelection>
    <FactSheets>
        <Sheet>
            <Program>Equity Hedge Legends</Program>
            <OrderID>82281</OrderID>
        </Sheet>
        <Sheet>
            <Program>Pinehurst</Program>
            <OrderID>82281</OrderID>
        </Sheet>
    </FactSheet>
    <ProductProfile>
        <Profile>
            <Program>Pinehurst</Program>
            <OrderID>82281</OrderID>
        </Profile>
        <Profile>
            <Program>Equity Hedge Legends</Program>
            <OrderID>82281</OrderID>
            </Profile>
    </ProductProfile>
  <Presentations>
        <Presentation>
            <Program>Equity Hedge Legends</Program>
            <OrderID>82281</OrderID>
        </Presentation>
        <Presentation>
            <Program>Pinehurst</Program>
            <OrderID>82281</OrderID>
        </Presentation>
  </Presentations>

请原谅我的格式,我是XML和XSLT的新手。 谢谢!!

2 个答案:

答案 0 :(得分:1)

尝试类似:

XSLT 1.0

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

<xsl:variable name="orderID" select="/Requests/Request/OrderID" />

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

<xsl:template match="FA | Prospect | ProgramSelection | FactSheet">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <OrderID><xsl:value-of select="$orderID"/></OrderID>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

使用原始发布的XML数据考虑以下XSLT。您需要使用xsl:for-each迭代每个子程序。

<强> XSLT

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />

<xsl:template match="Request">
<xsl:variable name="frnkey" select="OrderID"/>

 <Requests>  
  <ProgramSelection>
    <xsl:for-each select="ProgramSelection">
      <Selection>        
        <xsl:copy-of select="Interest"/>
        <xsl:copy-of select="Program"/>
        <OrderID><xsl:value-of select="$frnkey"/></OrderID>
      </Selection>
    </xsl:for-each>
  </ProgramSelection>

  <FactSheet>
    <xsl:for-each select="MarketingMaterial/FactSheet/Program">
     <Sheet>      
      <xsl:copy-of select="."/>
      <OrderID><xsl:value-of select="$frnkey"/></OrderID>
     </Sheet>
    </xsl:for-each>
  </FactSheet>

  <ProductProfile>
    <xsl:for-each select="MarketingMaterial/ProductProfile/Program">
     <Profile>      
      <xsl:copy-of select="."/>
      <OrderID><xsl:value-of select="$frnkey"/></OrderID>
     </Profile>
    </xsl:for-each>
  </ProductProfile>

  <Presentations>
    <xsl:for-each select="MarketingMaterial/Presentation/Program">
     <Presentation>      
      <xsl:copy-of select="."/>
      <OrderID><xsl:value-of select="$frnkey"/></OrderID>
     </Presentation>
    </xsl:for-each>
  </Presentations>

 </Requests>

</xsl:template>
</xsl:transform>

<强>输出

<?xml version="1.0" encoding="UTF-8"?>
<Requests>
  <ProgramSelection>
    <Selection>
      <Interest>I Interest</Interest>
      <Program>Hedge Funds &amp; Private Capital (Monthly Investment) Managed Futures &amp; Commodities Real Estate</Program>
      <OrderID>82281</OrderID>
    </Selection>
  </ProgramSelection>
  <FactSheet>
    <Sheet>
      <Program>Equity Hedge Legends</Program>
      <OrderID>82281</OrderID>
    </Sheet>
    <Sheet>
      <Program>Pinehurst</Program>
      <OrderID>82281</OrderID>
    </Sheet>
  </FactSheet>
  <ProductProfile>
    <Profile>
      <Program>Equity Hedge Legends</Program>
      <OrderID>82281</OrderID>
    </Profile>
    <Profile>
      <Program>Pinehurst</Program>
      <OrderID>82281</OrderID>
    </Profile>
  </ProductProfile>
  <Presentations>
    <Presentation>
      <Program>Equity Hedge Legends</Program>
      <OrderID>82281</OrderID>
    </Presentation>
    <Presentation>
      <Program>Pinehurst</Program>
      <OrderID>82281</OrderID>
    </Presentation>
  </Presentations>
</Requests>

除此之外 - 通常XSLT社区会劝告避免for-each looping(这让我想起R社区中使用apply family instead of for loop的辩论)。然而,只有在过度完成时,双方同意for循环并不是本质上的邪恶。出于MS Access导入的目的,必须为每个子项创建行和列二维结构的附加节点,这里可能是必要的。