XSLT: Как скопировать узлы, на которые ссылается id - PullRequest
0 голосов
/ 25 июня 2019

У меня есть следующий ввод:

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 Ответ

1 голос
/ 25 июня 2019

Я думаю, что вам нужен ключ <xsl:key name="inner-ref" match="compounddef" use="@id"/>, а затем вы обрабатываете / apply-templates значение 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...