Re: [xsl] Making a lookup structure from multiple documents

Subject: Re: [xsl] Making a lookup structure from multiple documents
From: "rick@xxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 13 Jun 2023 16:05:13 -0000
Now that I have collected my data from the entire ditamap hierarchy, I need to
make a second pass through the map and any referenced topics and use the
summary data in a particular element in one of the topics. I am not sure how
to go back to the beginning and process the map with the collected data from
the first pass. Here is my stylesheet:



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

    xmlns:xs="http://www.w3.org/2001/XMLSchema";

    xmlns:math="http://www.w3.org/2005/xpath-functions/math";

    xmlns:map="http://www.w3.org/2005/xpath-functions/map";

    exclude-result-prefixes="xs math map"

    version="3.0" expand-text="yes">



    <xsl:output indent="yes"/>



    <xsl:accumulator name="summary-data" initial-value="()" as="element()*">

        <xsl:accumulator-rule
match="*[@href[matches(.,'(dita(map)?|xml)$','i')]]">

            <xsl:sequence select="$value"/>

            <xsl:variable name="ref-path"
select="resolve-uri(@href,base-uri(.))"/>

            <xsl:if test="doc-available($ref-path)=true()">

                <xsl:apply-templates select="doc($ref-path)" mode="collect"/>

            </xsl:if>

        </xsl:accumulator-rule>

        <xsl:accumulator-rule match="tool" select="$value, ." />

        <xsl:accumulator-rule match="spare" select="$value, ." />

        <xsl:accumulator-rule match="supply" select="$value, ." />

    </xsl:accumulator>



    <xsl:mode name="collect" on-no-match="shallow-skip"
use-accumulators="summary-data"/>



    <xsl:template match="/" mode="collect">

        <xsl:apply-templates mode="#current"/>

        <xsl:sequence select="accumulator-after('summary-data')"/>

    </xsl:template>



    <xsl:template match="/">

        <!--<xsl:apply-templates/>-->

        <map-data>

            <summary>

                <xsl:for-each-group select="accumulator-after('summary-data')"
group-by="normalize-space(.)">

                    <xsl:sort select="local-name(.)"/>

                    <xsl:sort select="normalize-space(.)"/>

                    <xsl:element name="{local-name(.)}"><xsl:attribute
name="quantity"
select="sum(current-group()/@quantity)"/>{normalize-space(.)}</xsl:element>

                </xsl:for-each-group>

            </summary>

        </map-data>

    </xsl:template>



    <xsl:template
match="*[@href[matches(.,'(dita(map)?|xml)$','i')=true()]]">

        <xsl:variable name="ref-path"
select="resolve-uri(@href,base-uri(.))"/>

        <xsl:if test="doc-available($ref-path)=true()">

            <xsl:message>{$ref-path}</xsl:message>

            <xsl:apply-templates select="doc($ref-path)"/>

        </xsl:if>

    </xsl:template>



    <xsl:mode on-no-match="shallow-copy" use-accumulators="summary-data"/>



</xsl:stylesheet>



If I uncomment this:



    <xsl:template match="/">

        <!--<xsl:apply-templates/>-->



And try to insert the summary data in one of the topic elements, I just get
the data from that topic instead of what I have accumulated from the whole
map.



Rick



From: Martin Honnen martin.honnen@xxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Sent: Monday, June 12, 2023 3:21 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] Making a lookup structure from multiple documents





On 6/12/2023 8:49 PM, Martin Honnen martin.honnen@xxxxxx
<mailto:martin.honnen@xxxxxx>  wrote:



On 6/12/2023 8:33 PM, rick@xxxxxxxxxxxxxx <mailto:rick@xxxxxxxxxxxxxx>
wrote:

I am missing something fundamental here I think. My accumulator is collecting
the values from each topic separately, but I want it to accumulate the values
from the entire hierarchy before I use them. Here is my output:

Accumulator, like keys, work on a per document basis.

I will need to see whether you can combine an accumulator of the original
document with another on referenced documents; I think it is easy with
xsl:iterate or fold-left if you process a collection or uri collection but if
the processing is done lower in a template I don't have a better suggestion
currently than the above one.



I think the following might combine an accumulator on the map and on the
referenced documents:



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

    xmlns:xs= <http://www.w3.org/2001/XMLSchema>
"http://www.w3.org/2001/XMLSchema";

    xmlns:math= <http://www.w3.org/2005/xpath-functions/math>
"http://www.w3.org/2005/xpath-functions/math";

    xmlns:map= <http://www.w3.org/2005/xpath-functions/map>
"http://www.w3.org/2005/xpath-functions/map";

    exclude-result-prefixes="xs math map"

    version="3.0" expand-text="yes">



    <xsl:output indent="yes"/>


    <xsl:accumulator name="summary-data" initial-value="()" as="element()*">

        <xsl:accumulator-rule match=
<mailto:*[@href[matches(.,'(dita(map)?|xml)$','i')][doc-available(.)]]>
"*[@href[matches(.,'(dita(map)?|xml)$','i')][doc-available(.)]]">
           <xsl:sequence select="$value"/>
           <xsl:apply-templates select="doc(@href)" mode="collect"/>
        </xsl:accumulator-rule>

        <xsl:accumulator-rule match="tool" select="$value, ." />

        <xsl:accumulator-rule match="spare" select="$value, ." />

        <xsl:accumulator-rule match="supply" select="$value, ." />

    </xsl:accumulator>

    <xsl:mode name="collect" on-no-match="shallow-skip"
use-accumulators="summary-data"/>

    <xsl:template match="/" mode="collect">
      <xsl:apply-templates mode="#current"/>
      <xsl:sequence select="accumulator-after('summary-data')"/>
    </xsl:template>


    <xsl:template match="/">

    <doc>

        <xsl:apply-templates/>

        <xsl:for-each select="accumulator-after('summary-data')">

            <xsl:element name="{local-name(.)}"><xsl:attribute name="quantity"
select="./@quantity <mailto:./@quantity> "/>{.}</xsl:element>

        </xsl:for-each>

    </doc>

    </xsl:template>


    <xsl:mode on-no-match="shallow-skip" use-accumulators="summary-data"/>


</xsl:stylesheet>





XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>

EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/612310>  (by
email <> )

Current Thread