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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Want to process child and dec, Jason Davis nosaj3@x | Thread | Re: [xsl] Want to process child and, Eliot Kimber ekimber |
[xsl] Want to process child and dec, Jason Davis nosaj3@x | Date | Re: [xsl] Want to process child and, Graydon graydon@xxxx |
Month |