Re: [xsl] Want to process child and decendent nodes the same way as parent node but can only process children

Subject: Re: [xsl] Want to process child and decendent nodes the same way as parent node but can only process children
From: "Jason Davis nosaj3@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 16 Dec 2014 00:30:51 -0000
Sorry, I didn't post my style sheet in its entirety.

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

    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

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

    <xsl:key name="proc-num" match="map" use="keydef/@keys"/>

    <xsl:template match="/directory">
        <service-manual>
            <xsl:apply-templates select="file"/>
        </service-manual>
    </xsl:template>

    <xsl:template match="file">
        <xsl:variable name="path" select="@name"/>
        <xsl:for-each select="document($path)/task">
            <procedure>
                <name>
                    <xsl:value-of select="title"/>
                </name>
                <frt-num>
                    <xsl:value-of select="substring-after(@id,'X')"/>
                </frt-num>
                <xsl:apply-templates/>
            </procedure>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="//cmd/xref">
        <xsl:variable name="matching-proc" select="key('proc-num',
@keyref, document('serviceManLinkMap.ditamap'))"/>
        <xsl:variable name="name"
select="document('serviceManLinkMap.ditamap')/map/keydef/@href"/>
        <xsl:choose>
            <xsl:when test="$matching-proc">
                <child-proc>
                    <name>
                        <xsl:value-of select="document($name)/task[@id
= current()/@keyref]/title"/>
                    </name>
                    <frt-num>
                        <xsl:value-of
select="$matching-proc/keydef[@keys =
current()/@keyref]/substring-after(@keys,'X')"/>
                    </frt-num>
                </child-proc>
            </xsl:when>
            <xsl:otherwise>
                <child-proc>
                    <name>
                        <xsl:text>MISMATCH</xsl:text>
                    </name>
                    <frt-num>
                        <xsl:text>MISMATCH</xsl:text>
                    </frt-num>
                </child-proc>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="text()"/>

</xsl:stylesheet>

On Mon, Dec 15, 2014 at 4:18 PM, Jason Davis nosaj3@xxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
> I am currently trying to process multiple files for specific nodes and
> collect them in a meaningful way to demonstrate the parent-child
> relationship but I'm having trouble getting past the first level of
> children.
>
> Processor: Saxon PE 9.5.1.7
> Language version: 2.0
>
> A little background:
>
> I'm attempting to collect procedure codes from a service manual. The
> manual is composed of several XMLs. The procedures these codes refer
> to sometimes refer to subprocedures, which in turn may refer to
> subprocedures. The link relationship for these subprocedures is
> managed in a separate map file (also XML).
>
> What I want to do is list out all the procedure codes. If there is a
> subprocedure referenced in a procedure, I want to list its code as a
> child and continue in this way for all subprocedure until a procedure
> is listed that does not include a subprocedure.
>
> So far, it's really easy for me to:
>
>  - process all procedures (aggregated through a file list)
>  - list the @id (also doubles as the code number) for the procedure
>  - from a given procedure, process all `xref` nodes found in `cmd`
> nodes and list the `@keyref` value.
>
> The `@keyref` value in an xref is the same as the `@id` of the
> procedure to which it references. So, in a given procedure, any
> `cmd/xref/@keyref` value basically refers to a subprocedure. What I am
> attempting to capture is a list of all the `@id` values for procedures
> with subprocedures, and in turn, the `@id` of procedures that are
> subprocedures to subprocedures. I want to do this in a tree that makes
> the parent/child/descendant relationship clear in terms of what
> additional procedures someone needs to perform when performing a given
> procedure.
>
> Something like this:
>
>     <service-manual>
>       <procedure>
>          <name>3 Way Coolant Valve - Chiller Bypass (Remove and Replace)</name>
>          <frt-num>1234</frt-num>
>          <child-proc>
>             <frt-num>10040401</frt-num>
>             <child-proc>
>                <frt-num>3456</frt-num>
>                ...
>             </child-proc>
>             <child-proc>
>                <frt-num>4567</frt-num>
>                ...
>             </child-proc>
>          </child-proc>
>          <child-proc>
>             <frt-num>15240701</frt-num>
>             <child-proc>
>                <frt-num>1111</frt-num>
>                ...
>             </child-proc>
>             <child-proc>
>                <frt-num>2222</frt-num>
>                ...
>             </child-proc>
>          </child-proc>
>          ...
>       </procedure>
>        ...
>
> What I am having trouble with is figuring out how to process all the
> procedures an `xref` refers to and list that procedures' children. As
> previously mentioned, the link relationship is managed through a
> separate map. What this means is the `@keyref` in an `xref` is bound
> by a `keydef` element in the map. The keydef element contain two
> notable attributes: `@keys` which serves as the binding and an `href`
> that points to a specific resource.
>
> What it needs to do is:
>
>  - Figure out which `task` to which a given `@keyref` refers.
>  - List the `@id` of that `task` as a child to the current context.
>  - Continue processing all the `@keyrefs` in the same way in the decedent chain.
>
> The result that I'm getting from my style sheet is only processing the
> first set of children.
>
> Few things about this:
>
>  - In all cases, the outermost `task` node is the only relevant `@id`
> value I'm concerned with. Nested `task` nodes do not factor into this
> exercise.
>  - I want to capture all of this in a single XML.
>  - There are over 500 files referenced in the file list. So, I am just
> offering a partial sample here.
>
> The source XML looks like this:
>
>     <?xml version="1.0" encoding="UTF-8"?>
>     <!DOCTYPE task
>       PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd">
>     <task id="X1234">
>        <title>3 Way Coolant Valve - Chiller Bypass (Remove and Replace)</title>
>        <taskbody>
>           <prereq>
>              <p><b>FRT No: 1234</b></p>
>              <note
> conref="../../resources/SM-reuse.dita#topic_nsx_hq3_sl/Jack-Mode-Before-Lifting"/>
>              <p
> conref="../../resources/SM-reuse.dita#topic_nsx_hq3_sl/12v-warnings"/>
>           </prereq>
>        </taskbody>
>        <task id="d1e41176">
>           <title><ph
> conref="../../resources/SM-reuse.dita#topic_nsx_hq3_sl/removal-title"/></title>
>           <taskbody>
>              <steps>
>                 <step>
>                    <cmd>Some content for the step <xref
> keyref="X10040401">(refer to procedure)</xref>. </cmd>
>                 </step>
>                 <step>
>                    <cmd><ph
> conref="../../resources/SM-reuse.dita#topic_nsx_hq3_sl/disconnect-12v"
>                       /></cmd>
>                 </step>
>                 <step>
>                    <cmd>Some content for the steps <xref
> keyref="X15240701">(refer to
>                          procedure)</xref>.</cmd>
>                 </step>
>                 <step>
>                    <cmd>Some content for the step</cmd>
>                 </step>
>                 <step>
>                    <cmd>Some content for the step</cmd>
>                 </step>
>                 <step>
>                    <cmd>Some content for the step</cmd>
>                    <stepxmp>
>                       <fig>
>                          <xref href="repairimages/tss00168.jpg" format="jpg">
>     <image href="repairthumbs/tss00168.jpg"/>
>     </xref>
>                       </fig>
>                    </stepxmp>
>                 </step>
>                 <step>
>                    <cmd>Some content for the step</cmd>
>                 </step>
>                 <step>
>                    <cmd>Some content for the step</cmd>
>                    <stepxmp>
>                       <fig>
>                          <xref href="repairimages/tss00169.jpg" format="jpg">
>     <image href="repairthumbs/tss00169.jpg"/>
>     </xref>
>                       </fig>
>                    </stepxmp>
>                 </step>
>                 <step>
>                    <cmd>Some content for the step</cmd>
>                    <stepxmp>
>                       <fig>
>                          <xref href="repairimages/tss00170.jpg" format="jpg">
>     <image href="repairthumbs/tss00170.jpg"/>
>     </xref>
>                       </fig>
>                    </stepxmp>
>                 </step>
>              </steps>
>           </taskbody>
>        </task>
>        <task id="d1e41258">
>           <title><ph
> conref="../../resources/SM-reuse.dita#topic_nsx_hq3_sl/installation-title"/></title>
>           <taskbody>
>              <steps>
>                 <step>
>                    <cmd><ph
>
> conref="../../resources/SM-reuse.dita#topic_nsx_hq3_sl/Install-Reverse-Except"
>                       /></cmd>
>                    <info>
>                       <note
> conref="../../resources/SM-reuse.dita#topic_nsx_hq3_sl/Solvents-Ventilated"/>
>                       <note
> conref="../../resources/SM-reuse.dita#topic_nsx_hq3_sl/Clean-Before-Install"/>
>                    </info>
>                 </step>
>                 <step>
>                    <cmd>Some content for the step</cmd>
>                 </step>
>              </steps>
>           </taskbody>
>        </task>
>     </task>
>
> I am using a file list XML as input for processing multiple source
> files that looks like this:
>
>     <directory name="source" size="327680"
> lastModified="1416254183623" date="20141117T115623"
> absolutePath="C:\transform_lab\service_manual_projects\frt_work\source"
> sort="name" reverse="false">
>        <file name="12V_Positive_Jump_Post_(Remove_and_Replace).xml"
> size="3690" lastModified="1415930118927" date="20141113T175518"
> absolutePath="C:\transform_lab\service_manual_projects\frt_work\source\12V_Positive_Jump_Post_(Remove_and_Replace).xml"/>
>        <file name="200A_Fuses_-_Wall_Connector_(Remove_and_Replace).xml"
> size="12837" lastModified="1415930118958" date="20141113T175518"
> absolutePath="C:\transform_lab\service_manual_projects\frt_work\source\200A_Fuses_-_Wall_Connector_(Remove_and_Replace).xml"/>
>        <file name="2nd_Row_Center_Console_Assembly_(Remove_and_Replace).xml"
> size="2552" lastModified="1415930118990" date="20141113T175518"
> absolutePath="C:\transform_lab\service_manual_projects\frt_work\source\2nd_Row_Center_Console_Assembly_(Remove_and_Replace).xml"/>
>        <file name="3_Way_Coolant_Valve_-_Chiller_Bypass_(Remove_and_Replace).xml"
> size="3788" lastModified="1415930119021" date="20141113T175519"
> absolutePath="C:\transform_lab\service_manual_projects\frt_work\source\3_Way_Coolant_Valve_-_Chiller_Bypass_(Remove_and_Replace).xml"/>
>        ...
>     </directory>
>
> The key map for this project looks like this:
>
>     <map processing-role="resource-only">
>         <title>Service Manual Link Map</title>
>         <keydef keys="X1234"
>            href="../section_maps/topics/3_Way_Coolant_Valve_-_Chiller_Bypass_(Remove_and_Replace).xml"/>
>         ...
>         <keydef keys="X10040401"
>            href="../section_maps/topics/Raise_Vehicle_-_2_Post_Lift.xml"/>
>         <keydef keys="X15240701"
>            href="../section_maps/topics/Raise_Vehicle_-_4_Post_Lift.xml"/>
>         ...
>     </map>
>
>
> The style sheet I've developed looks like this:
>
>     <xsl:template match="/directory">
>         <service-manual>
>             <xsl:apply-templates select="file"/>
>         </service-manual>
>     </xsl:template>
>
>     <xsl:template match="file">
>         <xsl:variable name="path" select="@name"/>
>         <xsl:for-each select="document($path)/task">
>             <procedure>
>                 <name>
>                     <xsl:value-of select="title"/>
>                 </name>
>                 <frt-num>
>                     <xsl:value-of select="substring-after(@id,'X')"/>
>                 </frt-num>
>                 <xsl:apply-templates/>
>             </procedure>
>         </xsl:for-each>
>     </xsl:template>
>
>     <xsl:template match="//cmd/xref">
>         <xsl:variable name="matching-proc" select="key('proc-num',
> @keyref, document('serviceManLinkMap.ditamap'))"/>
>         <xsl:variable name="name"
> select="document('serviceManLinkMap.ditamap')/map/keydef/@href"/>
>         <xsl:choose>
>             <xsl:when test="$matching-proc">
>                 <child-proc>
>                     <name>
>                         <xsl:value-of select="document($name)/task[@id
> = current()/@keyref]/title"/>
>                     </name>
>                     <frt-num>
>                         <xsl:value-of
> select="$matching-proc/keydef[@keys =
> current()/@keyref]/substring-after(@keys,'X')"/>
>                     </frt-num>
>                 </child-proc>
>             </xsl:when>
>             <xsl:otherwise>
>                 <child-proc>
>                     <name>
>                         <xsl:text>MISMATCH</xsl:text>
>                     </name>
>                     <frt-num>
>                         <xsl:text>MISMATCH</xsl:text>
>                     </frt-num>
>                 </child-proc>
>             </xsl:otherwise>
>         </xsl:choose>
>     </xsl:template>
>
>     <xsl:template match="text()"/>
>
> This only gets me part of the way. With this, I'm able to process all
> the procedures that correlate to the value of `file` and process the
> `xrefs` of that procedure to find its subprocedures. However, I have
> not been able to figure out how to do the same with the subprocedures
> of a subprocedure.
>
> And believe me, I'm sure there are better ways to accomplish what I am
> attempting. So, any insights or suggestions for improvement, better
> efficiency, etc. are greatly appreciated. I'm pretty much an amateur
> with XSLT. So, please let me know if I am missing anything.
>
> Thanks,
> Jason

Current Thread