根据另一个xml节点值选择xml节点

时间:2012-02-21 16:31:27

标签: xml xslt xslt-1.0

xslt新手所以请耐心等待。我正在尝试将一个xml文档转换为另一个。我特别需要使用节点的值作为另一个节点的选择标准,但我不确定如何这样做。这类似于在SQL中使用外键将一个表连接到另一个表。

来源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 个答案:

答案 0 :(得分: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>