[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

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: Thu, 18 Dec 2014 17:38:07 -0000

Thanks for the links Elliot! This is good stuff. I always thought that
D4P was an interesting project but never took the time to explore it
much. After checking out the documentation, looks like there has been
a tremendous amount of work done on it. I plan to integrate its use
into the current tools and processes I currently manage.

Jason

On Tue, Dec 16, 2014 at 7:11 AM, Eliot Kimber ekimber@xxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
> Note that the DITA Community organization on GitHub
> (www.dita-community.org) provides general code for working with DITA
> source. The project org.dita-community.common.xslt
> (https://github.com/dita-community/org.dita-community.common.xslt)
> provides two libraries, relpath_util.xsl and dita-support-lib.xsl, that
> support pretty much anything you need to do with DITA in terms of
> resolving references, working with maps and topicrefs, and so on.
>
> Other projects under DITA Community provide examples of more involved DITA
> processing. The DITA for Publishers project (www.dita4publishers.org)
> provides addition libraries and code samples. In particular, it provides
> the "map-drive processing" framework for working with maps and the things
> they reference.
>
> Cheers,
>
> Eliot
> bbbbb
> Eliot Kimber, Owner
> Contrext, LLC
> http://contrext.com
>
>
>
>
> On 12/15/14, 6:30 PM, "Jason Davis nosaj3@xxxxxxxxx"
> <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
>>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-L
>>>ifting"/>
>>>              <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-Ex
>>>cept"
>>>                       /></cmd>
>>>                    <info>
>>>                       <note
>>>
>>>conref="../../resources/SM-reuse.dita#topic_nsx_hq3_sl/Solvents-Ventilate
>>>d"/>
>>>                       <note
>>>
>>>conref="../../resources/SM-reuse.dita#topic_nsx_hq3_sl/Clean-Before-Insta
>>>ll"/>
>>>                    </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\12
>>>V_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\20
>>>0A_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\2n
>>>d_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
Keywords
xml