Change attribute substring in node and all children

I did a bit of work and couldn't think of anything else using XSLT. I am trying to take an XML template (for McPAT, partially shown below), dictating system specifications and duplicating component id="system.core0" name="core0" node so that I can have N main nodes. Everyone will need to have "system.core #" as id and "core #" as the name of C #, which is the kernel number, 0-n.

I also have to duplicate this in any descendant nodes such as system.core0.itlb node below.

Also, in any of the descendant nodes with a value such as "config.system.cpu.clock", I need to add the number of node to "cpu".

Finally, I have to rewrite param name="number_of_cores" value="1" under the system with param name="number_of_cores" value="n" and change param name="homogenous_cores" value="1" to param name="homogenous_cores" value="0"

Currently, XML is as follows:

 <?xml version="1.0" ?> <component id="root" name="root"> <component id="system" name="system"> <param name="number_of_cores" value="1"/> <param name="homogeneous_cores" value="1"/> <param name="number_of_L1Directories" value="0"/> <param name="number_of_L2Directories" value="0"/> <param name="number_of_L2s" value="1"/> <param name="Private_L2" value="0"/> <param name="number_of_L3s" value="0"/> <param name="number_of_NoCs" value="1"/> ... <component id="system.core0" name="core0"> <!-- Core property --> <param name="clock_rate" value="{1e-6/config.system.cpu.clock*1e12}"/> <param name="opt_local" value="1"/> <stat name="total_instructions" value="{stats.system.cpu.iq.iqInstsIssued}"/> ... <component id="system.core0.itlb" name="itlb"> <param name="number_entries" value="{config.system.cpu.itb.size}"/> <stat name="total_accesses" value="{stats.system.cpu.itb.fetch_accesses}"/> ... </component> </component> </component> </component> 

There are a few lines here. I already went and copied system.core0 node N times, thanks to SO. I would post a link, but I cannot find the page. I know that Dimitry Novachev delivered the answer that I followed, and I would like to give him credit for his help in this. So far, the XSLT stylesheet looks like this:

 <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:param name="n" select="5"/> <!--Identity template--> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="component[@id='system']/component[@name='core0']"> <xsl:call-template name="copyNtimes"> <xsl:with-param name="n" select="$n"/> <xsl:with-param name="core_num" select="1"/> </xsl:call-template> </xsl:template> <xsl:template name="copyNtimes"> <xsl:param name="n" select="0"/> <xsl:param name="core_num" select="1"/> <xsl:if test="$n > 0"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> <xsl:text> </xsl:text> <xsl:call-template name="copyNtimes"> <xsl:with-param name="n" select="$n -1"/> <xsl:with-param name="core_num" select="$core_num+1"/> </xsl:call-template> </xsl:if> </xsl:template> </xsl:stylesheet> 

So, at the end of this process through xsltproc, I have the original with the system.core0 file duplicated N times. What was left drove me crazy for several days. How do I change the kernel numbers for each new node that I create, reflecting this in all the child nodes? Any help at all will help, even if it is not code. I played with creating new templates and using copies, but nothing seems to bring me any closer.

I could bring all this into another language, such as Perl, where I can run the XSLT stylesheet to duplicate the changes and manually change the attribute lines, if that is easier. I know that Perl has some pretty good modules for XML and XSLT. I feel that XSLT should be able to do this, and since I'm new to this, the format throws me off.

Edit : An example of the output of what I need looks something like this:

 <?xml version="1.0" ?> <component id="root" name="root"> <component id="system" name="system"> <param name="number_of_cores" value="3"/> <param name="homogeneous_cores" value="0"/> <param name="number_of_L1Directories" value="0"/> <param name="number_of_L2Directories" value="0"/> <param name="number_of_L2s" value="1"/> <param name="Private_L2" value="0"/> <param name="number_of_L3s" value="0"/> <param name="number_of_NoCs" value="1"/> <!--...--> <component id="system.core0" name="core0"> <!-- Core property --> <param name="clock_rate" value="{1e-6/config.system.cpu0.clock*1e12}"/> <param name="opt_local" value="1"/> <stat name="total_instructions" value="{stats.system.cpu0.iq.iqInstsIssued}"/> <!--...--> <component id="system.core0.itlb" name="itlb"> <param name="number_entries" value="{config.system.cpu0.itb.size}"/> <stat name="total_accesses" value="{stats.system.cpu0.itb.fetch_accesses}"/> ... </component> </component> <component id="system.core1" name="core1"> <!-- Core property --> <param name="clock_rate" value="{1e-6/config.system.cpu1.clock*1e12}"/> <param name="opt_local" value="1"/> <stat name="total_instructions" value="{stats.system.cpu1.iq.iqInstsIssued}"/> <!--...--> <component id="system.core1.itlb" name="itlb"> <param name="number_entries" value="{config.system.cpu1.itb.size}"/> <stat name="total_accesses" value="{stats.system.cpu1.itb.fetch_accesses}"/> ... </component> </component><component id="system.core2" name="core2"> <!-- Core property --> <param name="clock_rate" value="{1e-6/config.system.cpu2.clock*1e12}"/> <param name="opt_local" value="1"/> <stat name="total_instructions" value="{stats.system.cpu2.iq.iqInstsIssued}"/> <!--...--> <component id="system.core2.itlb" name="itlb"> <param name="number_entries" value="{config.system.cpu2.itb.size}"/> <stat name="total_accesses" value="{stats.system.cpu2.itb.fetch_accesses}"/> ... </component> </component> </component> </component> 
+5
source share
1 answer

(1) If you add the following two templates to your XSLT,

  <xsl:template match="param[@name='number_of_cores' and @value='1']"> <param name="number_of_cores" value="{$n}"/> </xsl:template> <xsl:template match="param[@name='homogeneous_cores' and @value='1']"> <param name="homogenous_cores" value="0"/> </xsl:template> 

you will override identity transformation and will be able to output various param elements as shown above.

(2) If you adjust the copy in copyNtimes as follows,

  <xsl:copy> <xsl:attribute name="id" select="concat('system.core', $n)"/> <xsl:attribute name="name" select="concat('core', $n)"/> <xsl:apply-templates select="node()"/> </xsl:copy> 

you will create copies not with copies, but copies, where @id and @name reflect the copy number passed to copyNtimes .

(3) If you additionally configure xsl:apply-template in copyNtimes on tunnel n (XSLT 2.0 is required),

  <xsl:apply-templates select="node()"> <xsl:with-param name="compNum" tunnel="yes" select="$n"/> </xsl:apply-templates> 

and also add a template to handle itlb components on the other side of the tunnel,

  <xsl:template match="component[@name='itlb']"> <xsl:param name="compNum" tunnel="yes"/> <component name="itlb" value="{concat('system.core',$compNum,'.itlb')}"> <xsl:apply-templates/> </component> </xsl:template> 

you can use the component number in the itlb components stream.

Updated (for the third time) full code and examples of XML input / output documents follow ...

This XML input document:

 <?xml version="1.0" ?> <component id="root" name="root"> <component id="system" name="system"> <param name="number_of_cores" value="1"/> <param name="homogeneous_cores" value="1"/> <param name="number_of_L1Directories" value="0"/> <param name="number_of_L2Directories" value="0"/> <param name="number_of_L2s" value="1"/> <param name="Private_L2" value="0"/> <param name="number_of_L3s" value="0"/> <param name="number_of_NoCs" value="1"/> <!-- ... --> <component id="system.core0" name="core0"> <!-- Core property --> <param name="clock_rate" value="{1e-6/config.system.cpu.clock*1e12}"/> <param name="opt_local" value="1"/> <stat name="total_instructions" value="{stats.system.cpu.iq.iqInstsIssued}"/> <!-- ... --> <component id="system.core0.itlb" name="itlb"> <param name="number_entries" value="{config.system.cpu.itb.size}"/> <stat name="total_accesses" value="{stats.system.cpu.itb.fetch_accesses}"/> <!-- ... --> </component> </component> </component> </component> 

Provided to this XSLT transformation:

 <?xml version="1.0"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:param name="n" select="5"/> <!--Identity template--> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="param[@name='number_of_cores' and @value='1']"> <param name="number_of_cores" value="{$n}"/> </xsl:template> <xsl:template match="param[@name='homogeneous_cores' and @value='1']"> <param name="homogenous_cores" value="0"/> </xsl:template> <xsl:template match="component[@name='itlb']"> <xsl:param name="compNum" tunnel="yes"/> <component name="itlb" value="{concat('system.core',$compNum,'.itlb')}"> <xsl:apply-templates/> </component> </xsl:template> <xsl:template match="component[@id='system']/component[@name='core0']"> <xsl:call-template name="copyNtimes"> <xsl:with-param name="n" select="$n"/> <xsl:with-param name="core_num" select="1"/> </xsl:call-template> </xsl:template> <xsl:template name="copyNtimes"> <xsl:param name="n" select="0"/> <xsl:param name="core_num" select="1"/> <xsl:if test="$n > 0"> <xsl:copy> <xsl:attribute name="id" select="concat('system.core', $n)"/> <xsl:attribute name="name" select="concat('core', $n)"/> <xsl:apply-templates select="node()"> <xsl:with-param name="compNum" tunnel="yes" select="$n"/> </xsl:apply-templates> </xsl:copy> <xsl:text> </xsl:text> <xsl:call-template name="copyNtimes"> <xsl:with-param name="n" select="$n -1"/> <xsl:with-param name="core_num" select="$core_num+1"/> </xsl:call-template> </xsl:if> </xsl:template> </xsl:stylesheet> 

Run this XML output:

 <?xml version="1.0" encoding="UTF-8"?> <component id="root" name="root"> <component id="system" name="system"> <param name="number_of_cores" value="5"/> <param name="homogenous_cores" value="0"/> <param name="number_of_L1Directories" value="0"/> <param name="number_of_L2Directories" value="0"/> <param name="number_of_L2s" value="1"/> <param name="Private_L2" value="0"/> <param name="number_of_L3s" value="0"/> <param name="number_of_NoCs" value="1"/> <!-- ... --> <component id="system.core5" name="core5"> <!-- Core property --> <param name="clock_rate" value="{1e-6/config.system.cpu.clock*1e12}"/> <param name="opt_local" value="1"/> <stat name="total_instructions" value="{stats.system.cpu.iq.iqInstsIssued}"/> <!-- ... --> <component name="itlb" value="system.core5.itlb"> <param name="number_entries" value="{config.system.cpu.itb.size}"/> <stat name="total_accesses" value="{stats.system.cpu.itb.fetch_accesses}"/> <!-- ... --> </component> </component> <component id="system.core4" name="core4"> <!-- Core property --> <param name="clock_rate" value="{1e-6/config.system.cpu.clock*1e12}"/> <param name="opt_local" value="1"/> <stat name="total_instructions" value="{stats.system.cpu.iq.iqInstsIssued}"/> <!-- ... --> <component name="itlb" value="system.core4.itlb"> <param name="number_entries" value="{config.system.cpu.itb.size}"/> <stat name="total_accesses" value="{stats.system.cpu.itb.fetch_accesses}"/> <!-- ... --> </component> </component> <component id="system.core3" name="core3"> <!-- Core property --> <param name="clock_rate" value="{1e-6/config.system.cpu.clock*1e12}"/> <param name="opt_local" value="1"/> <stat name="total_instructions" value="{stats.system.cpu.iq.iqInstsIssued}"/> <!-- ... --> <component name="itlb" value="system.core3.itlb"> <param name="number_entries" value="{config.system.cpu.itb.size}"/> <stat name="total_accesses" value="{stats.system.cpu.itb.fetch_accesses}"/> <!-- ... --> </component> </component> <component id="system.core2" name="core2"> <!-- Core property --> <param name="clock_rate" value="{1e-6/config.system.cpu.clock*1e12}"/> <param name="opt_local" value="1"/> <stat name="total_instructions" value="{stats.system.cpu.iq.iqInstsIssued}"/> <!-- ... --> <component name="itlb" value="system.core2.itlb"> <param name="number_entries" value="{config.system.cpu.itb.size}"/> <stat name="total_accesses" value="{stats.system.cpu.itb.fetch_accesses}"/> <!-- ... --> </component> </component> <component id="system.core1" name="core1"> <!-- Core property --> <param name="clock_rate" value="{1e-6/config.system.cpu.clock*1e12}"/> <param name="opt_local" value="1"/> <stat name="total_instructions" value="{stats.system.cpu.iq.iqInstsIssued}"/> <!-- ... --> <component name="itlb" value="system.core1.itlb"> <param name="number_entries" value="{config.system.cpu.itb.size}"/> <stat name="total_accesses" value="{stats.system.cpu.itb.fetch_accesses}"/> <!-- ... --> </component> </component> </component> </component> 
+3
source

Source: https://habr.com/ru/post/1202893/


All Articles