обновить более одного результата в одном и том же uri

Я хочу обновить тот же документ результатов, чтобы накапливать все метаэлементы. Я попытался воссоздать несколько шаблонов dita-ot, чтобы объяснить здесь проблему. Мой вопрос: можно ли обновить keyword.xml в

<xsl:template match="html" mode="pages"> 

сам шаблон? возможно, используя xsl: stream или xsl: аккумулятор? XSLT 3 и Saxon-HE-9.8.0-12

Входной XML

<root>
<article>
<html name="firsthtm">
    <head>Head1</head>
    <meta>keyword;firsthtm</meta>
</html>
<html name="secondhtm">
    <head>Head2</head>
    <meta>keyword;secondhtm</meta>
</html>
<html name="thirdhtm">
    <head>Head3</head>
    <meta>keyword;thirdhtm</meta>
</html>
</article>

XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="3.0">
<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="article">
    <xsl:apply-templates mode="pages"/>
</xsl:template>
<xsl:template match="html" mode="pages">
    <xsl:result-document href="{@name}.html">
        <html>
            <title>
                <xsl:value-of select="@name"/>
            </title>
        </html>
    </xsl:result-document>
    <!-- update keyword.xml for each html  -->
    <xsl:result-document href="keyword.xml">
        <root>
            <xsl:copy-of select="meta"/>
        </root>      
    </xsl:result-document>
</xsl:template>

 firsthtm.htm
 <html>
     <title>firsthtm</title>
 </html>

 secondhtm.htm
 <html>
     <title>secondhtm</title>
 </html>

 thirdhtm.htm
 <html>
     <title>thirdhtm</title>
 </html>

 keyword.xml
 <root>
     <meta>keyword;secondhtm</meta>
     <meta>keyword;secondhtm</meta>
     <meta>keyword;thridhtm</meta>
 </root>

person DitaNewbie La    schedule 20.08.2019    source источник


Ответы (2)


Просто создайте результирующий документ в шаблоне, соответствующем article:

<xsl:template match="article">
    <xsl:apply-templates mode="pages"/>
    <xsl:result-document href="keyword.xml">
        <root>
            <xsl:copy-of select="html/meta"/>
        </root>      
    </xsl:result-document>
</xsl:template>

Если вы хотите использовать match="html" mode="pages", вам нужно решить, какое совпадение вы хотите построить, например, на первом

<xsl:template match="html" mode="pages">
    <xsl:result-document href="{@name}.html">
        <html>
            <title>
                <xsl:value-of select="@name"/>
            </title>
        </html>
    </xsl:result-document>
    <!-- update keyword.xml for first html  -->
    <xsl:variable name="html-index" as="xs:integer">
      <xsl:number/>
    </xsl:variable>
    <xsl:if test="$html-index = 1">
      <xsl:result-document href="keyword.xml">
        <root>
            <xsl:copy-of select="ancestor::article/html/meta"/>
        </root>      
      </xsl:result-document>
    </xsl:if>
</xsl:template>

В простых случаях (есть только те html дочерние элементы для article, а вы использовали xsl:strip-space) может быть достаточно просто протестировать <xsl:if test="position() = 1">.

person Martin Honnen    schedule 20.08.2019
comment
Как получить такой же результат в ‹xsl: template match = html mode = pages›? это вообще возможно? - person DitaNewbie La; 20.08.2019
comment
@DitaNewbieLa, см. Правку, вы можете писать в один и тот же URI только один раз, поэтому вам нужно выбрать один из совпадающих элементов html для создания документа результата, а затем выбрать элементы meta. - person Martin Honnen; 20.08.2019

Простым решением было бы переместить xsl:result-document в шаблон article и скопировать оттуда все html/meta элементы:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="3.0">

    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="article">
        <xsl:apply-templates mode="pages"/>
        <xsl:result-document href="keyword.xml">
            <root>
                <xsl:copy-of select="html/meta"/>
            </root>            
        </xsl:result-document>
    </xsl:template>

    <xsl:template match="html" mode="pages">
        <xsl:result-document href="{@name}.html">
            <html>
                <title>
                    <xsl:value-of select="@name"/>
                </title>
            </html>
        </xsl:result-document>
        <!-- update keyword.xml for each html  -->
    </xsl:template>

</xsl:stylesheet>
person zx485    schedule 20.08.2019
comment
проблема в том, что код является частью настроенного плагина веб-справки dita-ot, и у меня есть доступ только к ‹xsl: template match = html mode = pages›. - person DitaNewbie La; 20.08.2019