2

Question 1: What is the cause of the xmns="" in <section>?

Question 2: why did the "epub" namespace in <section> vanish ?

Description of the problem:

I have an index.xml, which contains a list of XML files that I want to process with ONE XSLT file. The whole transformation and the looping etc goes well. This is the start of the index.xml file:

      <?xml version="1.0"?>
      <?xml-stylesheet type="text/xsl" href="file:///E:/toyota.xslt"?>
      <list>
        <entry>
            <file>01.xml</file>
        </entry>
        <entry>
            <file>02.xml</file>
        </entry>
        ... etc.

The file 01.xml is a mix of html tags and "special"tags (my own).

The file 01.xml looks like this:

    <?xml version="1.0" encoding="utf-8"?>
    <body>
        <section epub:type="frontmatter">
            <p>....</p>
            <p>....</p>
            <p>....</p>
        </section>
    </body>

This is part of toyota.xslt (which has grown rather long). Here you see the loop mechanism and the template that processes the <body> part of the <entry><file>:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:transform version="2.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:epub="http://www.idpf.org/2007/ops" exclude-result-prefixes="xs fn">
        <xsl:output method="xhtml" version="1.0" encoding="UTF-8" indent="yes"/>

        <xsl:template match="/">
            <xsl:apply-templates select="/list/entry"/>
        </xsl:template>
        <xsl:template match="entry">
            <xsl:variable name="filename" select="concat('new/' , substring-before( file, '.'), '.xhtml')"/>
            <xsl:result-document href="{$filename}" >
            <xsl:text disable-output-escaping="yes">
                &lt;!DOCTYPE html&gt;
            </xsl:text>
                <html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" lang="nl" xml:lang="nl">
                    <head>
                        <meta charset="utf-8" />
                        <title>
                            <xsl:value-of select="./title"/>
                        </title>

                    </head>
                    <xsl:apply-templates select="document(file)/body"/>
                </html>
            </xsl:result-document>
        </xsl:template>
        <xsl:template match="/body">
            <body>
                <xsl:apply-templates select="/body/@* | /body/node()"/>
            </body>
        </xsl:template>

I get this result (notice the superfluous xmlns attribute on <section>. I get them on other tags as well, but they have the same cause, I guess):

     <?xml version="1.0" encoding="UTF-8"?>
                <!DOCTYPE html>
            <html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" lang="nl" xml:lang="nl">
        <head>
            <meta charset="utf-8" />
            <title></title>
        </head>
        <body>
            <section xmlns="" type="frontmatter">
                <p> .... </p>
                <p> .... </p>       
            </section>
        </body>
     </html>              

I'm quite new to XSLT, but am proud to have this system working so far. With help. Now, this namespace issue... Btw: I use XMLSpy 2011.

2 Answers 2

3

Are you copying nodes from the secondary input file to the output? The secondary input file has elements in no namespace while the root of the result tree is in the XHTML namespace so that way to preserve the namespace of any copies in no namespace the serializer has to add xmlns="". The solution is not to copy the elements, instead you need to transform them with e.g.

<xsl:template match="section | p">
  <xsl:element name="{local-name()}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates select="@* | node()"/>
  </xsl:element>
</xsl:template>
Sign up to request clarification or add additional context in comments.

3 Comments

Yes, I copy too. I'll try your suggestions.
Point is, that only works for section and p. I need it on a lot of tags: i, q, p, section, li... Plus, the epub namespace question remains.
Well I could only list the names of elements you have shown, it shouldn't be too difficult to add other names to the match pattern: xsl:template match="section | p | i | q | li">. As an alternative define a mode that does <xsl:template match="*" mode="m1"><xsl:element name="{local-name()}" namespace="http://www.w3.org/1999/xhtml"><xsl:apply-templates select="@* | node()" mode="m1"/></xsl:element></xsl:template> and make sure you push your nodes through that mode with <xsl:apply-templates select="document(file)/body" mode="m1"/>.
1

I tried to create an XML from your series of input files, shown below (I have added a namespace declaration):

<?xml version="1.0" encoding="utf-8"?>
<body xmlns:epub="http://www.idpf.org/2007/ops">
    <section epub:type="frontmatter">
        <p>....</p>
        <p>....</p>
        <p>....</p>
    </section>
</body>

The following stylesheet is then applied to the above input XML:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="2.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:epub="http://www.idpf.org/2007/ops" exclude-result-prefixes="xs fn">
    <xsl:output method="xhtml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
        <xsl:variable name="filename" select="concat('new' , '.xhtml')"/>
        <xsl:result-document href="{$filename}" >
            <xsl:text disable-output-escaping="yes">
                &lt;!DOCTYPE html&gt;
            </xsl:text>
            <html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" lang="nl" xml:lang="nl">
                <head>
                    <meta charset="utf-8" />
                    <title>
                        <xsl:value-of select="./title"/>
                    </title>

                </head>
                <xsl:apply-templates select="body"/>
            </html>
        </xsl:result-document>
    </xsl:template>

    <xsl:template match="*">
        <xsl:element name="{local-name()}" namespace="http://www.w3.org/1999/xhtml">
            <xsl:if test="@*">
                <xsl:copy-of select="@*"/>
            </xsl:if>
            <xsl:apply-templates select="node()"/>
        </xsl:element>
    </xsl:template> 
</xsl:transform>

and the result is (filename: new.xhtml):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" lang="nl" xml:lang="nl">
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      <meta charset="utf-8" />
      <title></title>
   </head>
   <body>

      <section epub:type="frontmatter">

         <p>....</p>

         <p>....</p>

         <p>....</p>

      </section>

   </body>
</html>

3 Comments

Thanks for your suggestions: indeed, it seems that the <xsl:copy> is the cause: substituting with xsl:element does the trick for question 1. The epub issue remains, however.
I have modified my answer. Please have a look.
So you added a namespace to the body. Solves my problem indeed. thx a lot:)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.