XSLT: copy object xml multiple times while incrementing attribute and value

后端 未结 2 968
你的背包
你的背包 2021-01-07 01:40

I have a xml as below that I\'d like to copy n times while incrementing one of its element and one of its attribute.

XML input:



        
相关标签:
2条回答
  • 2021-01-07 02:05

    This transformation:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:t="http://test.com"
    >
         <xsl:output omit-xml-declaration="yes" indent="yes"/>
         <xsl:strip-space elements="*"/>
    
         <xsl:param name="pTimes" select="2"/>
    
         <xsl:template match="node()|@*">
          <xsl:param name="pPosition" select="1"/>
          <xsl:copy>
           <xsl:apply-templates select="node()|@*">
             <xsl:with-param name="pPosition" select="$pPosition"/>
           </xsl:apply-templates>
          </xsl:copy>
         </xsl:template>
    
         <xsl:template match="t:test">
             <xsl:call-template name="applyNTimes">
                 <xsl:with-param name="pTimes" select="$pTimes"/>
                 <xsl:with-param name="pPosition" select="1"/>
             </xsl:call-template>
         </xsl:template>
    
         <xsl:template name="applyNTimes">
             <xsl:param name="pTimes" select="0"/>
             <xsl:param name="pPosition" select="1"/>
    
             <xsl:if test="$pTimes > 0">
                 <xsl:choose>
                 <xsl:when test="$pTimes = 1">
                     <xsl:apply-templates select="*">
                     <xsl:with-param name="pPosition" select="$pPosition"/>
                     </xsl:apply-templates>
                 </xsl:when>
                 <xsl:otherwise>
                     <xsl:variable name="vHalf" select="floor($pTimes div 2)"/>
    
                     <xsl:call-template name="applyNTimes">
                     <xsl:with-param name="pTimes" select="$vHalf"/>
                     <xsl:with-param name="pPosition" select="$pPosition"/>
                     </xsl:call-template>
    
                     <xsl:call-template name="applyNTimes">
                     <xsl:with-param name="pTimes" select="$pTimes - $vHalf"/>
                     <xsl:with-param name="pPosition" select="$pPosition + $vHalf"/>
                     </xsl:call-template>
                 </xsl:otherwise>
                 </xsl:choose>
             </xsl:if>
         </xsl:template>
    
         <xsl:template match="t:Person">
             <xsl:param name="pPosition" select="1"/>
    
             <xsl:copy>
                 <xsl:copy-of select="@*"/>
                 <xsl:attribute name="position">
                  <xsl:value-of select="$pPosition"/>
                 </xsl:attribute>
                 <xsl:apply-templates>
                 <xsl:with-param name="pPosition" select="$pPosition"/>
                 </xsl:apply-templates>
              </xsl:copy>
         </xsl:template>
    
         <xsl:template match="t:number">
              <xsl:param name="pPosition" select="1"/>
                <xsl:copy>
                  <xsl:value-of select="$pPosition"/>
                </xsl:copy>
         </xsl:template>
    </xsl:stylesheet>
    

    when applied on the provided XML document:

    <header xmlns="http://test.com" >
        <Batch>
            <test document="dump" >
                <Person position="1">
                    <properties>
                        <name>John</name>
                        <number>1</number>
                    </properties>
                </Person>
            </test>
        </Batch>
    </header>
    

    produces the wanted results:

    <header xmlns="http://test.com">
        <Batch>
            <Person position="1">
                <properties>
                    <name>John</name>
                    <number>1</number>
                </properties>
            </Person>
            <Person position="2">
                <properties>
                    <name>John</name>
                    <number>2</number>
                </properties>
            </Person>
        </Batch>
    </header>
    
    0 讨论(0)
  • <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:t="http://test.com">
         <xsl:output omit-xml-declaration="yes" indent="yes"/>
         <xsl:strip-space elements="*"/>
         <xsl:param name="pTimes" select="2"/>
         <xsl:template match="node()|@*">
          <xsl:param name="pPosition" select="1"/>
          <xsl:copy>
           <xsl:apply-templates select="node()|@*">
             <xsl:with-param name="pPosition" select="$pPosition"/>
           </xsl:apply-templates>
          </xsl:copy>
         </xsl:template>
         <xsl:template match="t:test">
             <xsl:call-template name="applyNTimes">
                 <xsl:with-param name="pTimes" select="$pTimes"/>
                 <xsl:with-param name="pPosition" select="1"/>
             </xsl:call-template>
         </xsl:template>
         <xsl:template name="applyNTimes">
             <xsl:param name="pTimes" select="0"/>
             <xsl:param name="pPosition" select="1"/>
             <xsl:if test="$pTimes > 0">
                 <xsl:choose>`enter code here`
                 <xsl:when test="$pTimes = 1">
                     <xsl:apply-templates select="*">
                     <xsl:with-param name="pPosition" select="$pPosition"/>
                     </xsl:apply-templates>
                 </xsl:when>
                 <xsl:otherwise>
                     <xsl:variable name="vHalf" select="floor($pTimes div 2)"/>
                     <xsl:call-template name="applyNTimes">
                     <xsl:with-param name="pTimes" select="$vHalf"/>
                     <xsl:with-param name="pPosition" select="$pPosition"/>
                     </xsl:call-template>
                     <xsl:call-template name="applyNTimes">
                     <xsl:with-param name="pTimes" select="$pTimes - $vHalf"/>
                     <xsl:with-param name="pPosition" select="$pPosition + $vHalf"/>
                     </xsl:call-template>
                 </xsl:otherwise>
                 </xsl:choose>
             </xsl:if>
         </xsl:template>
         <xsl:template match="t:Person">
             <xsl:param name="pPosition" select="1"/>
             <xsl:copy>
                 <xsl:copy-of select="@*"/>
                 <xsl:attribute name="position">
                  <xsl:value-of select="$pPosition"/>
                 </xsl:attribute>
                 <xsl:apply-templates>
                 <xsl:with-param name="pPosition" select="$pPosition"/>
                 </xsl:apply-templates>
              </xsl:copy>
         </xsl:template>
         <xsl:template match="t:number">
              <xsl:param name="pPosition" select="1"/>
                <xsl:copy>
                  <xsl:value-of select="$pPosition"/>
                </xsl:copy>
         </xsl:template>
    </xsl:stylesheet>
    
    0 讨论(0)
提交回复
热议问题