如何使用xslt用newNode事务替换案例节点事务

时间:2014-09-19 06:43:52

标签: xml xslt-1.0

下面是输入XML:

<?xml version="1.0" encoding="UTF-8"?>
<DST>
  <CDGCreateTree>
    <DST>
      <currentJobName>PQContactComplete</currentJobName>
      <AWD>
        <case>
          <transaction>
            <UIID>001</UIID>
          </transaction>
        </case>
        <case>
          <transaction>
            <UIID>002</UIID>
          </transaction>
        </case>
      </AWD>
    </DST>
  </CDGCreateTree>
  <newNode>
    <transaction relate="Y" id="1"/>   
  </newNode>
</DST>
  1. 在上面的XML总共2 case s中有个人transaction s
  2. newNode节点包含另一个ID为transaction
  3. id="1"

    我的要求是,我希望先将case transaction替换为newNode transaction

    结果应该是:

    <?xml version="1.0" encoding="UTF-8"?>
    <DST>
      <CDGCreateTree>
        <DST>
          <currentJobName>PQContactComplete</currentJobName>
          <AWD>
            <case>
               <transaction relate="Y" id="1"/>   
            </case>
            <case>
              <transaction>
                <UIID>002</UIID>
              </transaction>
            </case>
          </AWD>
        </DST>
      </CDGCreateTree> 
    </DST>
    

    将来,我可能会在transaction节点下获得id的另一个newNode。下面是XML

    <?xml version="1.0" encoding="UTF-8"?>
    <DST>
      <CDGCreateTree>
        <DST>
          <currentJobName>PQContactComplete</currentJobName>
          <AWD>
            <case>
               <transaction relate="Y" id="1"/>   
            </case>
            <case>
              <transaction>
                <UIID>002</UIID>
              </transaction>
            </case>
           </AWD>
        </DST>
      </CDGCreateTree> 
      <newNode>
        <transaction relate="Y" id="2"/>   
      </newNode>
    </DST>
    

    这次我应该用case transaction替换第二个newNode transaction(因为第一个case transaction已经拥有id }值)。 我想以这种方式继续这个过程。

    我在下面尝试过XSLT,但它没有帮助。如果我错了,请建议更好的方法或纠正我。

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version = "1.0">
    
        <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()" />
            </xsl:copy>         
        </xsl:template>
    
        <xsl:variable name="targetNode" select="//newNode/transaction"/>
    
        <xsl:template match="(//transaction[ancestor::*[name() = "CDGCreateTree"]][not(@id)])[1]">
            <xsl:copy-of select="$targetNode"/>
        </xsl:template>
    
        <xsl:template match="//newNode">
        </xsl:template>
    
    </xsl:stylesheet>
    

    上述XSL的解释:

    (//transaction[ancestor::*[name() = "CDGCreateTree"]][not(@id)])[1]此声明是关于case transaction的定义,其中没有id和第一transaction 替换为(//newNode/transaction)transaction

    将来,如果我得到任何newNode transaction,则应相应地替换为上述XSL。我认为它会按照声明工作,但缺少一些东西。

2 个答案:

答案 0 :(得分:0)

我仍然不确定我完全理解这一点,但请尝试:

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:key name="new-transaction" match="newNode/transaction" use="count(preceding-sibling::transaction)" />

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

<xsl:template match="case/transaction[key('new-transaction', count(preceding::transaction))]">
    <xsl:copy-of select="key('new-transaction', count(preceding::transaction))"/>
</xsl:template>

<xsl:template match="newNode"/>

</xsl:stylesheet>

这将用旧的交易取代旧交易,按文件顺序进行,直到没有更多的新交易(在这种情况下保留剩余的旧交易),或者直到没有更多的旧交易(在这种情况下,剩余的新交易)交易被丢弃),这是最先出现的。

应用于小型化输入示例

<?xml version="1.0" encoding="UTF-8"?>
<DST>
  <CDGCreateTree>
    <DST>
      <currentJobName>PQContactComplete</currentJobName>
      <AWD>
        <case>
           <transaction>
            <UIID>001</UIID>
          </transaction>
        </case>
        <case>
          <transaction>
            <UIID>002</UIID>
          </transaction>
        </case>
        <case>
          <transaction>
            <UIID>003</UIID>
          </transaction>
        </case>
      </AWD>
    </DST>
  </CDGCreateTree>
  <newNode>
    <transaction relate="Y" id="1"/>
    <transaction relate="Y" id="2"/>
  </newNode>
</DST>

结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<DST>
   <CDGCreateTree>
      <DST>
         <currentJobName>PQContactComplete</currentJobName>
         <AWD>
            <case>
               <transaction relate="Y" id="1"/>
            </case>
            <case>
               <transaction relate="Y" id="2"/>
            </case>
            <case>
               <transaction>
                  <UIID>003</UIID>
               </transaction>
            </case>
         </AWD>
      </DST>
   </CDGCreateTree>
</DST>

答案 1 :(得分:0)

1)In first loop suppose count value contains 1, case transaction replaced with new transaction which contains.
2)In second loop the count value contains 2, so the second case transaction replaced with newNode transaction which contains.
3)Always newNode transaction contains new transaction which is generated dynamically.

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

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

<xsl:variable name="counter" select="//sample/count"/>

<xsl:variable name="targetNode" select="//newNode/transaction"/>

<xsl:template match="case[$counter]/transaction">
   <xsl:copy-of select="$targetNode"/>
</xsl:template>

<xsl:template match="//sample/count">
<count>
   <xsl:value-of select="$counter + 1"/>
 </count>
</xsl:template>

</xsl:stylesheet>