XSLT:如何复制ID引用的节点

时间:2019-06-25 08:07:17

标签: xml xslt

我有以下输入内容:

input.xml

<compounddef xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="about" kind="page">
    <title>About This Document</title>
    <innerpage refid="t1">Item1</innerpage>
    <innerpage refid="t2">Item2</innerpage>
</compounddef> 

<compounddef xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="t1" kind="page">
   <title>This is item 1</title>
</compounddef> 

<compounddef xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="t2" kind="page">
   <title>This is item 2</title>
</compounddef> 

我正在尝试按父页面内的内部页面嵌套页面引用。即预期输出应为:

expected_output.xml

<compounddef xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="about" kind="page">
    <title>About This Document</title>
    <innerpage refid="t1">Item1</innerpage>
    <innerpage refid="t2">Item2</innerpage>

    <sect1 id=t1>
        <title>This is item 1</title>
    </sect1>

    <sect1 id=t2>
        <title>This is item 2</title>
    </sect1>

</compounddef> 

在给定页面中可以是0到许多内部页面。 目前,我能够将所有内部页面嵌套在所有非内部页面中。使用以下xslt。

transform.xslt

    <xsl:key name="inner-page-ref" match="compounddef[@kind='page']/innerpage" use="@refid"/>
    <!-- remove unmatched -->
    <xsl:template match="text()"/>


   <xsl:template match="/doxygen">
        <doxygen version="{@version}">
            <xsl:apply-templates select = "compounddef[@kind='page' and not(key('inner-page-ref', @id))]"/> 
        </doxygen>
    </xsl:template>


    <xsl:template match="doxygen/compounddef/innerpage" mode="list"> 
        <innerpage> 
            <xsl:value-of select="text()"/>
        </innerpage>
    </xsl:template>

    <xsl:template match="doxygen/compounddef/innerpage" mode="body"> 
        <xsl:copy>
            <xsl:apply-templates select = "/doxygen/compounddef[@kind='page' and key('inner-page-ref', @id)]"/> 
        </xsl:copy>
    </xsl:template>

    <xsl:template match="doxygen/compounddef[@kind='page'and not(key('inner-page-ref', @id))]"> 
            <compounddef id="{@id}" kind="{@kind}">
                <title><xsl:value-of select="title"/></title>
                <xsl:apply-templates mode="list" select = "innerpage"/>
                <xsl:apply-templates mode="body" select = "innerpage"/>
           </compounddef>
    </xsl:template>

    <xsl:template match="doxygen/compounddef[@kind='page'and (key('inner-page-ref', @id))]"> 

            <xsl:message> innerpage <xsl:value-of select ="@refid"/> </xsl:message>
            <sect1 id="{@id}">
                <title><xsl:value-of select="title"/></title>
            </sect1>
    </xsl:template>

我需要创建一个页面列表,这些页面是特定页面的子页面,任何页面仅适用于它们。但是还找不到办法。 任何提示将不胜感激。

谢谢, 伊利亚

1 个答案:

答案 0 :(得分:1)

我认为您想要一个密钥<xsl:key name="inner-ref" match="compounddef" use="@id"/>,然后您将模板处理/应用于select="key('inner-ref', innerpage/@hrefid)",因为这是所引用的“列表”(XSLT 1中的节点集,XSLT 2中的序列) compounddef个元素中的innerpage个元素。

一个更完整的例子是

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

   <xsl:output indent="yes"/>
   <xsl:strip-space elements="*"/>

   <xsl:key name="inner-ref" match="compounddef" use="@id"/>
   <xsl:key name="inner-page-ref" match="compounddef[@kind='page']/innerpage" use="@refid"/>

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

   <xsl:template match="/doxygen">
        <doxygen version="{@version}">
            <xsl:apply-templates select = "compounddef[@kind='page' and not(key('inner-page-ref', @id))]"/> 
        </doxygen>
    </xsl:template>

    <xsl:template match="compounddef">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
            <xsl:apply-templates select="key('inner-ref', innerpage/@refid)" mode="sect"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="compounddef" mode="sect">
            <sect1 id="{@id}">
                <title><xsl:value-of select="title"/></title>
            </sect1>
    </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/ncdD7n5

有输出

<doxygen version="">
  <compounddef id="about" kind="page" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <title>About This Document</title>
    <innerpage refid="t1">Item1</innerpage>
    <innerpage refid="t2">Item2</innerpage>
    <sect1 id="t1">
      <title>This is item 1</title>
    </sect1>
    <sect1 id="t2">
      <title>This is item 2</title>
    </sect1>
  </compounddef>
</doxygen>