Search code examples
xmlxsltadobe-indesign

Invalid namespace error when importing XML into InDesign with xslt


When I attempt to import an XML file into InDesign using an XSLT stylesheet, I get "DOM transformation error: Invalid namespace" and the import fails. I've tried the solution mentioned in this post, but it doesn't work for me: Namespace error when importing XML-file into InDesign. I have been unable to find any other posts that deal with this issue directly.

At its simplest, my code looks like this. I've stripped everything else away, and this still fails for me.

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/"
    xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">

<xsl:template match="/">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="book">
   <book xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
      <xsl:apply-templates/>
   </book>
</xsl:template>

</xsl:stylesheet>

Incidentally, when I transform the XML with this code outside of InDesign in a test environment, I can import the resulting XML with no issues, which leads me to believe that it's an InDesign issue rather than an XSLT issue. I've looked through my XSLT for another namespace that might not have gotten declared, but I can't find anything.

Any insight is greatly appreciated!


Solution

  • For anyone that might encounter this issue in the future, I was able to resolve this issue following the example in the Plugin SDK in the XSL files located in: source/sdksamples/xdocbookworkflow/examplefiles

    Basically, here are the rules (and steps will follow):

    1. The source XML should not contain any namespaces. Those are introduced during import using the import stylesheet.
    2. The root element must contain the namespace definitions.
    3. Namespaces cannot be processed directly and must be added using variables.

    The XSL processing engine is pretty picky about namespaces, even Adobe's aid and aid5 namespaces. If they are in your source XML, you can import them without any issues if you don't associate an import XSL stylesheet. As soon as you add the stylesheet, the namespaces will break the import with an 'Invalid Namespace' error.

    Adding the namespace to the root element is simply a workaround by creating a dummy attribute:

    <xsl:template match="root-element">
    <copy>
      <xsl:variable name="ns">aid</xsl:variable>
      <xsl:attribute
        name="{concat($ns, ':role')}"
        namespace="http://ns.adobe.com/AdobeInDesign/4.0/">force-namespace</xsl:attribute>
      <xsl:apply-templates/>
    </copy>
    </xsl:template>
    

    The aid:role attribute is not an actually an attribute, but must be used to force the namespace to behave correctly. Then for each attribute that uses a namespace, you construct the attribute in the same way:

    <xsl:template match="root/title">
      <xsl:copy>
        <xsl:variable name="ns">aid</xsl:variable>
        <xsl:attribute
          name="{concat($ns, ':pstyle')}"
          namespace="http://ns.adobe.com/AdobeInDesign/4.0/">doc-title</xsl:attribute>
          <xsl:apply-templates/>
      </xsl:copy>
    </xsl:template>
    

    In my case, my source XML contained widths for table cells, so I had to convert the attribute names to the correct aid namespace so that the InDesign tables could identify and apply the correct value. Here was how I handled that:

    <xsl:template match="@cellwidth">
      <xsl:variable name="idns">aid</xsl:variable>
      <xsl:attribute name="{concat($idns,':ccolwidth')}"
        namespace="http://ns.adobe.com/AdobeInDesign/4.0/">
        <xsl:value-of select="."/>
      </xsl:attribute>
    </xsl:template>  
    

    For a full example of how this works, refer to the XSL stylesheets in the SDK location specified above.