OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

docbook-apps message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: Re: [docbook-apps] Namespace question


Hi Dick,

On Donnerstag, 20. März 2008, Dick Hamilton wrote:
> Is there a way to tell a stylesheet to process an instance
> in namespace X, as though it were really in namespace Y?
>
> E.g., suppose I get a boatload of content from a customer
> marked up in a minor variant of docbook identified with a
> different namespace (e.g., xmlns="http://myschema.org/";).
> Even though that's not the best way to identify a DocBook
> variant, let's assume I can't edit their source, and I
> don't want to edit the standard stylesheets.
>
> Instead, I'd like to do something in my customization layer
> that effectively tells the imported stylesheets to treat
> input in the "http://myschema.org/"; namespace as though it
> were in the docbook namespace.
>
> Anyone have any suggestions?

There are two methods for your problem:

A. The two-step-approach
B. The multi-pass approach

Let's look first into (A) and assume, your XML file looks like this:

-----[ chapter.xml ]-----
<chapter xmlns="http://myschema.org/";
  xmlns:xlink="http://www.w3.org/1999/xlink";>
  <?dbfoo hello?>
  <title>The Strange Namespace</title>
  <!-- A comment -->
  <para>Foo <link xlink:href="foo"/>.</para>
</chapter>
-------------------------

Do the following:

1. Use the following stylesheet to renames the myschema namespace into the 
DocBook5 namespace:

-----[ rename2db5.xsl ]-----
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  xmlns:d="http://docbook.org/ns/docbook";
  xmlns:m="http://myschema.org/";
  exclude-result-prefixes="m">

<xsl:output indent="yes" method="xml"/>

<xsl:preserve-space elements="m:screen m:programlisting"/>
<xsl:strip-space elements="m:*"/>
  

<xsl:template match="/">
  <xsl:choose>
    <xsl:when test="namespace-uri(*) = 'http://myschema.org/'">
      <xsl:apply-templates mode="rename"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:message>
        <xsl:text>ERROR: Not the correct namespace. </xsl:text>
        <xsl:text>Expected 'http://myschema.org/'.</xsl:text>
      </xsl:message>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="m:*" mode="rename">
   <xsl:element name="{local-name(.)}" 
     namespace="http://docbook.org/ns/docbook";>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates mode="rename"/>
  </xsl:element>
</xsl:template>

<xsl:template match="comment()" mode="rename">
  <xsl:copy-of select="."/>
</xsl:template>

<xsl:template match="processing-instruction()" mode="rename">
  <xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>
----------------------------

That gives you the following output:


---------[ Output ]---------
<?xml version="1.0"?>
<chapter xmlns="http://docbook.org/ns/docbook";>
  <?dbfoo hello?>
  <title>The Strange Namespace</title>
  <!-- A comment -->
  <para>Foo <link xmlns:xlink="http://www.w3.org/1999/xlink"; 
xlink:href="foo"/>.</para>
</chapter>
----------------------------

2. Apply your customization layer to the above output.


If you prefer the multi-pass approach, you could use the following 
technique. See [1] for more details. However, it relies on the extension 
function exslt:node-set. If you have very big documents it can also be a 
matter of memory consumption.

----------------------------
<xsl:stylesheet version="1.0"
  xmlns:d="http://docbook.org/ns/docbook";
  xmlns:exslt="http://exslt.org/common";
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  exclude-result-prefixes="exslt d">

<xsl:import 
href="http://docbook.sourceforge.net/release/xsl-ns/current/xhtml/docbook.xsl"/>
<xsl:import href="rename2db5.xsl"/>

<xsl:template match="/">
  <xsl:if test="namespace-uri(*) != 'http://myschema.org/'">
    <xsl:message terminate="yes"></xsl:message>
  </xsl:if>
  <!-- Maybe check here, if exslt:node-set exists in your XSLT
       processor -->
  <xsl:variable name="rtf">
    <xsl:apply-templates mode="rename"/>
  </xsl:variable>
  
  <xsl:apply-templates select="exslt:node-set($rtf)/*"/>
</xsl:template>

</xsl:stylesheet>
----------------------------



Hope that helps,
Tom


---- References
[1] http://www.ibm.com/developerworks/xml/library/x-tipxsltmp.html

-- 
Thomas Schraitle


[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]