如何使用xslt将case节点事务替换为newNode事务



下面是输入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个cases,它具有单独的transactions
  2. newNode节点包含另一个ID为(id="1")的transaction

我的要求是,我想用newNode transaction 替换第一个case 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>

将来我可能会在newNode节点下得到另一个具有idtransaction。下面是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>

这一次,我应该用newNode transaction替换第二个case 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]该语句定义了不具有id和第一个transactioncase transaction替换为(//newNode/transaction)新的transaction

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

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

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)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>

最新更新