2014-09-18 116 views
5

我已经完成了相当多的搜索,并且还没有完全能够使用XSLT提出任何问题。我正在尝试使用一个XML模板(对于McPAT,部分显示如下)来指定系统规格并复制component id="system.core0" name="core0"节点,以便我可以有N个核心节点。每个人都必须具有“system.core#”作为id,“core#”作为名称,其中#是核心编号0-n。修改节点中的属性子串和所有子节点

我还必须在任何后代节点(如下面的system.core0.itlb节点)中复制此节点。更进一步,在任何具有诸如“config.system.cpu.clock”等值的后代节点中,我必须将节点号附加到“cpu”。

最后,我必须覆盖 param name="number_of_cores" value="1" 下系统 param name="number_of_cores" value="n" 和改变 param name="homogenous_cores" value="1"param name="homogenous_cores" value="0"

的XML目前看起来是这样的:

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

有相当多的线在这里。由于SO,我已经复制了system.core0节点N次。我会张贴链接,但我找不到该页面。我知道Dimitre Novatchev提出了我所遵循的答案,我想借此机会向他表示赞赏。到目前为止,XSLT样式表看起来是这样的:

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

因此,在通过xsltproc的运行这个月底,我有system.core0原来的重复N次。剩下的几天让我疯狂了好几天。我如何着手改变我创建的每个新节点的核心数字,并在所有子节点中反映这一点?任何帮助都将有所帮助,即使它不是代码。我已经尝试过制作新的模板和使用副本,但似乎没有任何东西让我更接近。

我也可以将这一切都带入另一种语言,比如Perl,在那里我可以运行XSLT样式表来复制更改并手动修改属性字符串(如果这样会更容易)。我知道Perl为XML和XSLT提供了一些相当不错的模块。尽管如此,我认为XSLT应该可以做到这一点,而且由于我刚刚接触它,这种格式正在让我失望。

编辑: 什么,我需要一个例子输出是这样的:

<?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> 
+0

从哪里值'n'来自新的'param name =“number_of_cores”value =“n”'?始终来自XSLT中名为'n'的全局参数? – kjhughes 2014-09-18 16:17:51

+0

在XSLT样式表中,我将它作为参数传递,设置在文件的顶部。我假设我可以在那里使用它,但如果这是不可能的,我相信我可以在顶部发表评论,以便在不同的地方修改n。 – 2014-09-18 16:20:31

+0

这似乎是一个合法的问题,但很难理解散文。请显示实际的XML输出并解释它与您需要的不同之处。 – 2014-09-18 16:28:45

回答

3

(1)如果以下两个模板添加到您的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> 

您将覆盖身份转换并能够输出不同的param元素,如上所示。

(2)如果调整内copyNtimes复制如下,

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

你会不会产生碳副本,但副本,其中@id@name反映传递给copyNtimes拷贝数。

(3)如果进一步调整copyNtimesxsl:apply-template到隧道n(XSLT 2.0需要),

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

,并且还添加模板在隧道的另一侧处理itlbcomponents

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

你能工作的组件数量为后代itlbcomponents

更新(第三次)完整的代码和样本输入/输出XML文档遵循...

此输入XML文档:

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

鉴于此XSLT转换:

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

将产生这个输出X ML文档:

<?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> 
+0

这实际上正是我所需要的那个问题!我还需要为核心的每个独立实例将core0更改为core0,core1,core2,...,core(n-1)。 – 2014-09-18 16:39:43

+0

答复已更新。你在这里得到两个答案的价格。 ;-) – kjhughes 2014-09-18 16:53:08

+0

谢谢!这绝对是非常有帮助的!有没有一种方法可以将相同的逻辑应用于后代节点,例如,在“system.core4”下,会有一个组件“system.core4.itlb”而不是“system.core0” .itlb“ – 2014-09-18 17:01:18