2012-02-21 178 views
1

xslt的新功能,請耐心等待。我試圖將一個XML文檔轉換爲另一個。我特別需要使用節點的值作爲另一個節點的選擇標準,但我不確定如何去做。這將類似於在SQL中使用外鍵將一個表連接到另一個表。基於另一個xml節點值選擇xml節點

源XML:

<?xml version="1.0" encoding="utf-8" ?> 
<AbleCommerceExport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Store> 
    <StoreId>1</StoreId> 
    <Name>My Store</Name> 
    <Products> 
     <Product> 
    <ProductOptions> 
     <ProductOption> 
     <ProductId>2</ProductId> 
     <OptionId>3</OptionId> 
     <OrderBy>0</OrderBy> 
     <Option> 
      <Choices> 
     <Choice> 
      <OptionChoiceId>8</OptionChoiceId> 
      <OptionId>3</OptionId> 
      <Name>3'10" x 5'4"</Name> 
     </Choice> 
     <Choice> 
      <OptionChoiceId>9</OptionChoiceId> 
      <OptionId>3</OptionId> 
      <Name>5'4" x 7'8"</Name> 
     </Choice> 
     <Choice> 
      <OptionChoiceId>10</OptionChoiceId> 
      <OptionId>3</OptionId> 
      <Name>7'8" x 10'9"</Name> 
     </Choice> 
      </Choices> 
     </Option> 
     </ProductOption> 
    </ProductOptions> 
    <Variants> 
     <ProductVariant> 
     <Available>true</Available> 
     <ProductVariantId>49</ProductVariantId> 
     <ProductId>2</ProductId> 
     <Option1>8</Option1> 
     <Option2>0</Option2> 
     <Option3>0</Option3> 
     <Option4>0</Option4> 
     <Option5>0</Option5> 
     <Option6>0</Option6> 
     <Option7>0</Option7> 
     <Option8>0</Option8> 
     </ProductVariant> 
     <ProductVariant> 
     <Available>true</Available> 
     <ProductVariantId>50</ProductVariantId> 
     <ProductId>2</ProductId> 
     <Option1>9</Option1> 
     <Option2>0</Option2> 
     <Option3>0</Option3> 
     <Option4>0</Option4> 
     <Option5>0</Option5> 
     <Option6>0</Option6> 
     <Option7>0</Option7> 
     <Option8>0</Option8> 
     </ProductVariant> 
     <ProductVariant> 
     <Available>true</Available> 
     <ProductVariantId>51</ProductVariantId> 
     <ProductId>2</ProductId> 
     <Option1>10</Option1> 
     <Option2>0</Option2> 
     <Option3>0</Option3> 
     <Option4>0</Option4> 
     <Option5>0</Option5> 
     <Option6>0</Option6> 
     <Option7>0</Option7> 
     <Option8>0</Option8> 
     </ProductVariant> 
    </Variants> 
     </Product> 
    </Products> 
    </Store> 
</AbleCommerceExport> 

期望中的XML輸出:

<RECORDS> 
    <RECORD><!-- For each <ProductVariant> node--> 
     <RECORD_ID ID="49" /> 
     <PROP NAME="ProductVariantId"> 
      <PVAL>49</PVAL> 
     </PROP> 
     <PROP NAME="Available"> 
      <PVAL>true</PVAL> 
     </PROP> 
     <!-- For each Option[n] retrieve the /Products/Product/ProductOptions/ProductOption/Option/Choices/Choice/Name value --> 
     <PROP NAME="Option"> 
      <PVAL>3'10" x 5'4"</PVAL> 
     </PROP> 
     <PROP NAME="Option"> 
      <PVAL>5'4" x 7'8"</PVAL> 
     </PROP> 
     <PROP NAME="Option"> 
      <PVAL>7'8" x 10'9"</PVAL> 
     </PROP> 
    </RECORD> 
<RECORDS> 

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" indent="yes"/> 

    <xsl:template match="Variants"> 
    <RECORDS> 
     <xsl:apply-templates/> 
    </RECORDS> 
    </xsl:template> 

    <xsl:template match="ProductVariant"> 
    <RECORD> 
     <xsl:element name="RECORD_ID"> 
     <xsl:attribute name="ID"> 
      <xsl:value-of select="ProductVariantId"/> 
     </xsl:attribute> 
     </xsl:element> 

    <!--??--> 

    </RECORD> 
    </xsl:template> 

    <xsl:template match="text()" /> 

</xsl:stylesheet> 

感謝提前任何幫助。

回答

1

這種轉變

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

<xsl:template match="Product"> 
    <RECORDS> 
    <xsl:apply-templates select="Variants/ProductVariant"> 
    <xsl:with-param name="pOptions" select= 
    "ProductOptions/*/Option/*/*"/> 
    </xsl:apply-templates> 
    </RECORDS> 
</xsl:template> 

<xsl:template match="ProductVariant"> 
    <xsl:param name="pOptions"/> 
    <RECORD> 
     <RECORD_ID ID="{ProductVariantId}"/> 
     <xsl:apply-templates select="Available|ProductVariantId"/> 
     <xsl:apply-templates select= 
     "*[starts-with(name(), 'Option') and number(.)]"> 
     <xsl:with-param name="pOptions" select="$pOptions"/> 
     </xsl:apply-templates> 
    </RECORD> 
</xsl:template> 

<xsl:template match="*[starts-with(name(), 'Option')]"> 
    <xsl:param name="pOptions"/> 

    <PROP NAME="Option"> 
    <PVAL> 
     <xsl:value-of select= 
     "$pOptions[OptionChoiceId=current()]/Name"/> 
    </PVAL> 
    </PROP> 
</xsl:template> 

<xsl:template match="Available|ProductVariantId"> 
    <PROP NAME="{name()}"> 
    <PVAL><xsl:value-of select="."/></PVAL> 
    </PROP> 
</xsl:template> 

<xsl:template match="text()"/> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<AbleCommerceExport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Store> 
     <StoreId>1</StoreId> 
     <Name>My Store</Name> 
     <Products> 
      <Product> 
       <ProductOptions> 
        <ProductOption> 
         <ProductId>2</ProductId> 
         <OptionId>3</OptionId> 
         <OrderBy>0</OrderBy> 
         <Option> 
          <Choices> 
           <Choice> 
            <OptionChoiceId>8</OptionChoiceId> 
            <OptionId>3</OptionId> 
            <Name>3'10" x 5'4"</Name> 
           </Choice> 
           <Choice> 
            <OptionChoiceId>9</OptionChoiceId> 
            <OptionId>3</OptionId> 
            <Name>5'4" x 7'8"</Name> 
           </Choice> 
           <Choice> 
            <OptionChoiceId>10</OptionChoiceId> 
            <OptionId>3</OptionId> 
            <Name>7'8" x 10'9"</Name> 
           </Choice> 
          </Choices> 
         </Option> 
        </ProductOption> 
       </ProductOptions> 
       <Variants> 
        <ProductVariant> 
         <Available>true</Available> 
         <ProductVariantId>49</ProductVariantId> 
         <ProductId>2</ProductId> 
         <Option1>8</Option1> 
         <Option2>0</Option2> 
         <Option3>0</Option3> 
         <Option4>0</Option4> 
         <Option5>0</Option5> 
         <Option6>0</Option6> 
         <Option7>0</Option7> 
         <Option8>0</Option8> 
        </ProductVariant> 
        <ProductVariant> 
         <Available>true</Available> 
         <ProductVariantId>50</ProductVariantId> 
         <ProductId>2</ProductId> 
         <Option1>9</Option1> 
         <Option2>0</Option2> 
         <Option3>0</Option3> 
         <Option4>0</Option4> 
         <Option5>0</Option5> 
         <Option6>0</Option6> 
         <Option7>0</Option7> 
         <Option8>0</Option8> 
        </ProductVariant> 
        <ProductVariant> 
         <Available>true</Available> 
         <ProductVariantId>51</ProductVariantId> 
         <ProductId>2</ProductId> 
         <Option1>10</Option1> 
         <Option2>0</Option2> 
         <Option3>0</Option3> 
         <Option4>0</Option4> 
         <Option5>0</Option5> 
         <Option6>0</Option6> 
         <Option7>0</Option7> 
         <Option8>0</Option8> 
        </ProductVariant> 
       </Variants> 
      </Product> 
     </Products> 
    </Store> 
</AbleCommerceExport> 

產生想要的,正確的結果

<RECORDS> 
    <RECORD> 
     <RECORD_ID ID="49"/> 
     <PROP NAME="Available"> 
     <PVAL>true</PVAL> 
     </PROP> 
     <PROP NAME="ProductVariantId"> 
     <PVAL>49</PVAL> 
     </PROP> 
     <PROP NAME="Option"> 
     <PVAL>3'10" x 5'4"</PVAL> 
     </PROP> 
    </RECORD> 
    <RECORD> 
     <RECORD_ID ID="50"/> 
     <PROP NAME="Available"> 
     <PVAL>true</PVAL> 
     </PROP> 
     <PROP NAME="ProductVariantId"> 
     <PVAL>50</PVAL> 
     </PROP> 
     <PROP NAME="Option"> 
     <PVAL>5'4" x 7'8"</PVAL> 
     </PROP> 
    </RECORD> 
    <RECORD> 
     <RECORD_ID ID="51"/> 
     <PROP NAME="Available"> 
     <PVAL>true</PVAL> 
     </PROP> 
     <PROP NAME="ProductVariantId"> 
     <PVAL>51</PVAL> 
     </PROP> 
     <PROP NAME="Option"> 
     <PVAL>7'8" x 10'9"</PVAL> 
     </PROP> 
    </RECORD> 
</RECORDS> 
+0

即使我提供的所需xml不正確(每個單個記錄節點有多個prop節點),也可以獲得正確答案。 謝謝你的幫助。 – user1223750 2012-02-21 18:06:53

+0

@ user1223750:我很高興我的回答對你有用。您能否請*接受*答案(提示:點擊答案旁邊的複選標記)? – 2012-02-21 18:11:10

+0

當然。試圖投票,但沒有足夠的信譽。再次感謝。 – user1223750 2012-02-21 18:16:11