« It could be worse | Main | Hamas wins Palestinian elections, part V »

January 29, 2006

Children of multiple parents and XSL

One thing Matt did in his configuration mapping was to define a sort of object inheritence mechanism. Similar configuration objects inherit their attributes from abstract parents, so similar configuration objects can share children.

Big deal? Well, yeah, not really. Except in terms of how this works for documentation.

One of the output formats for the documentation of this configuration interface is man pages. My aim is to be able to let the reader type man configuration-object-name or man configuration-object-attribute-name and either way get the doc. The man command, at least on Solaris systems, supports two kinds of pages, regular pages, pages containing normal content, and shadow pages, pages that point to regular pages. Shadow pages can only point to one other page, however, not multiple pages. Thus for configuration attributes present on many objects, I created individual pages, which reference the parent configuration objects having the attribute as a child, but also document the child. Furthermore, the way the man command on Solaris systems works, I didn't want to reference the child-of-multiple-parent attributes in the RefName elements of the parent pages. That would've gummed up the works of our tools to build books from RefEntry elements, which is what I'm constructing.

Okay, if you're still with me, you'll see that I needed a way to determine which of Matt's XML children had multiple parents, and which did not. The language to transform his XML into SolBook (like DocBook) RefEntrys is XSLT. After struggling stupidly with XPath expressions for a while, I found somebody's email that put me onto the scent of xsl:key elements.

What I did in the end was first to write a first XSL transformation to flatten Matt's document. By flatten, I mean the first stylesheet leaves only concrete configuration objects that directly include their inherited attributes. Other than that it simply makes copies of the content. Making a whole new document is probably a waste in terms of system resources, but it sure makes things easier for the human being grasping to understand the problem.

Next I create xsl:key elements, one on the parents indexed by name, one on the children, indexed by name. Keys are created as top level elements. When I then come to the point in the stylesheet where I need to decide whether a child has a single parent or multiple parents, I can just select the parents of the child using the key() function. In the second stylesheet, I have the following:

<xsl:key name="children" match="child" use="@name" />
<xsl:key name="parents" match="parent" use="child/@name" />
...
<xsl:for-each select="parent/child">
<xsl:sort select="@name" />
<xsl:choose>
<xsl:when test="count(key('children', @name))=1">
<!-- Child is unique. Make a shadow page. -->
<xsl:call-template name="shadow">
<xsl:with-param name="child" select="@name" />
<xsl:with-param name="parent" select="../@name" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- Child is a duplicate. Make a real page. -->
<xsl:variable name="multiple" select="key('parents', @name)" />
<xsl:call-template name="real">
<xsl:with-param name="child" select="." />
<xsl:with-param name="parents" select="$multiple" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>

Notice the count() function is the test to check whether there's one or multiple parents.

Posted by Mark at January 29, 2006 08:54 AM

Trackback Pings

TrackBack URL for this entry:
http://mcraig.org/movabletype/mt-tb.cgi/1298

Comments

Sorry, can't help you with your specific problem because I can't be bothered to learn XSLT this quickly. But you do make me think of a similar conceptual problem I've noticed recently in HTML, and by extension in how our need to reference knowledge is limited by our tools.

Concretely, why can't we have a link that points to several targets (ie multiple href attributes in the anchor tag)? It seems so straightforward to process: if it's a file to download, just download multiple files; if it's a page to open, just open several windows or tabs, if you don't know how to handle it, just open the first one. I thought of this because I wanted to create a link that would download several files, without having to zip them up into one.

I guees the answer is that Firefox is open source and I just need to go write my extension. Then, if it's a good and useful idea, it will be adopted. I just can't believe nobody's done it yet.

Posted by: Andy at January 30, 2006 10:41 PM

Don't worry, I've solved what I needed to solve. Most of these entries are just for searchable notes to self.

The reason we cannot have links to several targets today is that the tools don't handle it. The shadow (pointer) page even becomes a file system link in the roff version of the pages, so you're stuck on most filesystems. True, the formatter could just pick the first link and give up on the rest. But the people writing the formatters and the people creating the pages are on different paths.

In the end, for the children with multiple parents, I generate a list of references (that become links in the HTML for example). So it's not an automatic redirect, but it's also some fairly useful contextual links, unlike certain ads.

Posted by: Mark at January 31, 2006 05:53 PM