在xsl中为每个进程处理两个

时间:2016-03-30 11:07:38

标签: xml xslt xml-parsing

我想在xsl中为每个节点处理两个单独的节点。问题How do I access elements from the outer loop from within nested loops?看起来很相似。我试过,但即使使用变量后也没有工作。不知道我做错了什么。

这是xml:

<root>
    <demomain>
        <demo>
            <name>A</name>
            <price>10</price>

        </demo>
        <demo>
            <name>B</name>
            <price>15</price>

        </demo>
    <demomain>
    <demomainOrig>
        <demoOrig>
            <name>A</name>
            <price>20</price>           
        </demoOrig>
        <demoOrig>
            <name></name>
            <price>25</price>           
        </demoOrig>
    </demomainOrig>
</root>

到目前为止我所做的xsl是

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
<demos>
     <xsl:for-each select="root/demomain/demo">
    <xsl:variable name="newNode" select="."/>
         <Demo>
            <productID id="{$newNode/name}"/>
<xsl:for-each select="root/demomainOrig/demoOrig">
            <price newVal="{$newNode/price}" origVal="{price}" />
    </xsl:for-each>
        </Demo>
    </xsl:for-each>
</demos>

</xsl:template>
</xsl:stylesheet> 

以下是我想要的输出:

<?xml version="1.0" encoding="UTF-8"?>
<demos>
   <Demo>
      <productID id="A"/>
      <price newVal="10" origVal="20"/>
   </Demo>
   <Demo>
      <productID id="B"/>
      <price newVal="15" origVal="25"/>
   </Demo>
</demos>

问题在于每个人的内心。如果我删除内部的每个我得到输出中的价格标签,否则它甚至不显示。所以我无法获得特定商品的原价。请帮助。

先谢谢

2 个答案:

答案 0 :(得分:1)

问题出在这条线上......

<xsl:for-each select="root/demomainOrig/demoOrig">

此时您位于demo元素上,因此这将查找名为root的子元素。但是您的root是整个文档的根元素。应该这样......

<xsl:for-each select="/root/demomainOrig/demoOrig">

但是,这仍然不能满足您的需求,因为这会选择所有demoOrig元素。您只想选择具有相同名称的那个:

<xsl:for-each select="/root/demomainOrig/demoOrig[name = $newNode/name]">

试试这个XSLT

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

<xsl:template match="/">
    <demos>
       <xsl:for-each select="root/demomain/demo">
        <xsl:variable name="newNode" select="."/>
            <Demo>
                <productID id="{$newNode/name}"/>
                <xsl:for-each select="/root/demomainOrig/demoOrig[name=$newNode/name]">
                    <price newVal="{$newNode/price}" origVal="{price}" />
                </xsl:for-each>
            </Demo>
        </xsl:for-each>
    </demos>
</xsl:template>
</xsl:stylesheet> 

我假设您的实际XML已为所有name元素指定了demoOrig

实际上,您可以用一个语句替换xsl:for-each

<price newVal="{$newNode/price}" origVal="{/root/demomainOrig/demoOrig[name=$newNode/name]/price}" />

或者,您可以使用xsl:key查找记录。也试试这个XSLT

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

<xsl:key name="orig" match="demoOrig" use="name" />

<xsl:template match="/">
    <demos>
       <xsl:for-each select="root/demomain/demo">
        <xsl:variable name="newNode" select="."/>
            <Demo>
                <productID id="{name}"/>
                <price newVal="{price}" origVal="{key('orig', name)/price}" />
            </Demo>
        </xsl:for-each>
    </demos>
</xsl:template>
</xsl:stylesheet> 

答案 1 :(得分:1)

您可以使用当前节点的相同位置来获取相应的demoOrig节点(假设订单相同,并且&#39; name&#39;不是标识符)。

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <demos>
     <xsl:for-each select="root/demomain/demo">
        <xsl:variable name="position" select="position()" />
        <xsl:variable name="demoOrig" select="/root/demomainOrig/demoOrig[position() = $position]" />
       <Demo>
        <productID id="{name}"/>
        <price newVal="{price}" origVal="{$demoOrig/price}" />
      </Demo>
    </xsl:for-each>
  </demos>

  </xsl:template>
</xsl:stylesheet>

输出:

<?xml version="1.0" encoding="UTF-8"?>
<demos>
   <Demo>
      <productID id="A" />
      <price origVal="20" newVal="10" />
   </Demo>
   <Demo>
      <productID id="B" />
      <price origVal="25" newVal="15" />
   </Demo>
</demos>