在同一个uri中更新多个结果

时间:2019-08-20 17:49:12

标签: xslt-2.0 xslt-3.0

我想更新同一结果文档以累积所有元元素。我试图重新创建多个dita-ot模板以在这里解释问题。我的问题是,是否可以在

中更新keyword.xml
<xsl:template match="html" mode="pages"> 

模板本身?也许使用xsl:stream或xsl:accumulator? 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>

2 个答案:

答案 0 :(得分:1)

只需在匹配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">就足够了。

答案 1 :(得分:0)

一个简单的解决方案是将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>