xml:lang

1. xml:lang issues
2. Copy xml:lang attribute

1.

xml:lang issues

Michael Kay



> If you don't think it's a problem in practice, what about taking the 
> xml-to-xhtml XSLT associated with the xmlspec DTD, and change it so 
> that multilingual input is output with the correct xml:lang attributes 
> (but without having xml:lang on every element if not necessary).

There are lots of things in XSLT that aren't easy, such as processing CALS table models. But on the scale of problems this one is by no means difficult: for example it can be done by running a three-phase transformation in which a pre-processing phase adds redundant xml:lang attributes:

<xsl:template match="*">
  <xsl:copy>
    <xsl:copy-of select="@* | ancestor-or-self::*/@xml:lang[last()]"/>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

and a post-processing phase removes redundant xml:lang attributes:

<xsl:template match="*">
  <xsl:copy>
    <xsl:copy-of select="@* except @xml:lang[. =
ancestor::*/@xml:lang[last()]]"/>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

When I said it doesn't seem to be a problem in practice, I meant that I don't see evidence of lots of users trying to do this and complaining that it's difficult. I see a lot more complaints about the difficulty of handling CALS table models. For a problem that doesn't arise often in practice, a solution in 12 lines of code seems good enough.

Inherited attributes are a bit of an oddity. Formally, there is no such thing as an inherited attribute, it's only a design convention, and there are lots of different variations on it - xml:space, xml:base, and xml:lang work quite differently from each other. Without a formalisation of inherited attributes in the data model and in the XML Schema type system, it's not easy to come up with language constructs that would be generic enough to be useful, and an ad-hoc solution for one particular attribute would be really bad design, especially in the absence of any evidence of a pressing user problem.

2.

Copy xml:lang attribute

Martin ??


 How to create a stlyesheet that cleanly copies xml:lang:
 [assuming for simplicity that all xml:lang information is comming 
 from the source, not from the stylesheet, and that only whole 
 elements are transferred, not independent textual pieces] [I'm using 
 a tree-pass solution; this could be done in many cases as a two-pass 
 solution]

Start with your stylesheet. Make sure that on all elements, xml:lang is copied. Assumes that the main mode for the original stylesheet is the default mode.

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

 <xsl:template match="*" mode="expandXmlLang">
    <xsl:copy>
      <xsl:copy-of select="@* |
 ancestor-or-self::*/@xml:lang[last()]"/>
      <xsl:apply-templates mode="expandXmlLang"/>
    </xsl:copy>
 </xsl:template>

 <xsl:template match="*" mode="cleanXmlLang">
    <xsl:copy>
      <xsl:copy-of select="@* except @xml:lang[. = 
 ancestor::*/@xml:lang[last()]]"/>
      <xsl:apply-templates mode="cleanXmlLang"/>
    </xsl:copy>
 </xsl:template>

 <!-- rest of your stylesheet here or somewhere -->

 <xsl:variable name="xmlLangExpanded">
    <xsl:apply-templates select="/" mode="expandXmlLang"/> 
 </xsl:variable>

 <xsl:variable name="processedMain">
    <xsl:apply-templates select="$xmlLangExpanded" mode="#default"/> 
 </xsl:variable>

 <xsl:template match="/">
    <xsl:apply-templates select"$processedMain" mode="cleanXmlLang"/> 
 <xsl:template> </xsl:stylesheet>