I have a xml file whose structure looks like this:
<root>
<includes>
<includeFile name="../other/some_xml.xml"/>
</includes>
<itemlist>
<item id="1" >
<selections>
<selection name="one" />
</selections>
</item>
</itemlist>
The xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt">
<xsl:output method="xml" indent="yes" xalan:indent-amount="4" />
<xsl:template match="/">
<xsl:element name="ItemList">
<xsl:if test="root/item">
<xsl:call-template name="templ" />
</xsl:if>
</xsl:element>
</xsl:template>
<xsl:template name="templ">
<xsl:element name="ItemList">
<xsl:for-each select="root/itemlist/item">
<xsl:element name="Item">
<xsl:element name="ItemIdentifier">
<xsl:value-of select="#id" />
</xsl:element>
<xsl:element name="Condition">
<xsl:value-of select="selections/selection[1]/#name" />
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
I created one XSLT which i am using to filter out items. The problem is that for every file, i have to check if it contains the includefile tag, which is a relative path pointing to a similar xml, and if it does, i need to collect items from that file also, recursively. For now i transformed the xml using my xslt and then i have to parse the xml to look for includefile tag. This solution doesn't look elegant and i was wondering if all of it could be done via xslt.
The XSLT document function in XSLT 1.0 and in XSLT 2.0 additionally the doc function allow you to pull in further documents, processing is then simply possible with matching templates. So consider to move your XSLT coding style to write matching templates and apply-templates, then you can easily do
<xsl:template match="includes/includeFile">
<xsl:apply-templates select="document(#name)/*"/>
<xsl:template>
and then you simply need to make sure the <xsl:template match="root">...</xsl:template> creates the output you want.
Related
My First question is marked as duplicated, but it isn't a duplicate
show XML in HTML with inline stylesheet
I hope this question is not immediatley marked as duplicate, only because one of the moderators has read the first two sentences and've ignored the rest.
The Problem is not to show an XML Structure in HTML, rather to show a full dynamically XML structure, with all tags and occasional colored lines.
The structure and interior fields are full dynamically and every field can be correct or wrong, depending on the xml file like to compare.
So a field is at the first comparison correct, but on another comparison it’s wrong. The fields and structure of XML can vary greatly from one comparison to another.
I’m looking since yesterday for a corresponding and professional solution for this problem.
Background process: comparison different xml files, via soa microservices in java. The comparison is made by org.custommonkey.xmlunit. The Result have to be an html popup, what shows me differences marked by colored lines.
Example Output XUnit Diff Result XPath
/ROOT[1]/MATDETAIL[1]/OUTPUT[1]/GENERAL[1]/CHANGED_BY[1]/text()[1]
Transform the source xml via xslt and the xunit diff result informations.
Example Input XML
<ROOT>
<MATDETAIL>
<OUTPUT>
<GENERAL>
<CREATED_ON/>
<CREATED_BY>ORIGINAL USER</CREATED_BY>
<LAST_CHNGE/>
<CHANGED_BY>NEW USER</CHANGED_BY>
</GENERAL>
<RETURN>
<TYPE>S</TYPE>
<MESSAGE/>
<LOG_NO/>
<LOG_MSG_NO>000000</LOG_MSG_NO>
</RETURN>
</OUTPUT>
</MATDETAIL>
</ROOT>
Example XSL Transformation
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node() | #*">
<xsl:copy>
<xsl:apply-templates select="node() | #*" mode="unescape"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/ROOT[1]/MATDETAIL[1]/OUTPUT[1]/GENERAL[1]/CHANGED_BY[1]">
<xsl:element name = "span">
<xsl:attribute name="style">font-weight:bold; color:red </xsl:attribute>
<xsl:copy>
<xsl:value-of select = "current()" />
</xsl:copy>
<xsl:text><== Expected: dasda</xsl:text>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Example Result of XSL Transformation
<ROOT>
<MATDETAIL>
<OUTPUT>
<GENERAL>
<CREATED_ON/>
<CREATED_BY>ORIGINAL USER</CREATED_BY>
<LAST_CHNGE/>
<span style="font-weight:bold; color:red "><CHANGED_BY>NEW USER</CHANGED_BY><== Expected: ORIGINAL USER</span>
</GENERAL>
<RETURN>
<TYPE>S</TYPE>
<MESSAGE/>
<LOG_NO/>
<LOG_MSG_NO>000000</LOG_MSG_NO>
</RETURN>
</OUTPUT>
</MATDETAIL>
</ROOT>
I’m not able to show this xml structure in html, with (all) tags, correctly AND colored.
Either I’ve get no tags, so there are only the raw data in XML to see, without tags, but the lines are colored.
Or I get the xml structure with all data, but not colored.
I tried to replace the lt and gt chars inside xslt, but failed, or after transformation in java, this result shows very ugly. My colleague has meant that we can not use it in any way.
Because the XML Structur can be every time different and so on fully dynamically, I can not style the xml with css and tag definition.
Unfortunately, alternative implementations are not an option. I have to do this somehow with the means available to me. (Java, XML & XSL, JS, HTML, CSS).
I hope to get good ideas to solute this.
I would like to thank you in advance.
I hope i can solve your issue with following try.
I. Input:
<ROOT baum="baum">
<MATDETAIL>
<OUTPUT>
<GENERAL>
<CREATED_ON/>
<CREATED_BY>ORIGINAL USER</CREATED_BY>
<LAST_CHNGE/>
<CHANGED_BY>NEW USER</CHANGED_BY>
</GENERAL>
<RETURN>
<TYPE>S</TYPE>
<MESSAGE/>
<LOG_NO/>
<LOG_MSG_NO>000000</LOG_MSG_NO>
</RETURN>
</OUTPUT>
</MATDETAIL>
</ROOT>
II. Stylesheet (XSLT 1.0):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="CHANGED_BY">
<span style="color:red;">
<xsl:apply-templates select="." mode="serialize"/>
</span>
</xsl:template>
<xsl:template match="*">
<xsl:apply-templates select="." mode="serialize"/>
</xsl:template>
<xsl:template match="#*">
<xsl:apply-templates select="." mode="serialize"/>
</xsl:template>
<xsl:template match="*" mode="serialize">
<xsl:value-of select="concat('<', name())"/>
<xsl:apply-templates select="#*" />
<xsl:choose>
<xsl:when test="node()">
<xsl:text>></xsl:text>
<xsl:apply-templates />
<xsl:value-of select="concat('<', name(), '>')"/>
</xsl:when>
<xsl:otherwise>
<xsl:text> /></xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="#*" mode="serialize">
<xsl:value-of select="concat(' ', name(), '="', ., '"')"/>
</xsl:template>
<xsl:template match="text()" mode="serialize">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
III: Output:
<ROOT baum="baum">
<MATDETAIL>
<OUTPUT>
<GENERAL>
<CREATED_ON />
<CREATED_BY>ORIGINAL USER</CREATED_BY>
<LAST_CHNGE />
<span style="color:red;"><CHANGED_BY>NEW USER</CHANGED_BY></span>
</GENERAL>
<RETURN>
<TYPE>S</TYPE>
<MESSAGE />
<LOG_NO />
<LOG_MSG_NO>000000</LOG_MSG_NO>
</RETURN>
</OUTPUT>
</MATDETAIL>
</ROOT>
IV. Explanation:
Whenever the mode="serialize" is applied, the context is escaped. See example for CHANGED_BY to format with HTML-Tags. The xml structure is fully escaped so the browser shows it like a string instead of tags.
I really hope it solves your problem
I have two .xml files which need to be joined
The first file is Song.xml as the following:
<Songs>
<Song>
<SongID>1</SongID>
<SongName>We dont talk anymore</SongName>
<Author>M-TP</Author>
<UploadBy>admin</UploadBy>
<GerneCode>1</GerneCode>
</Song>
</Songs>
and the Gerne.xml which generate from a schema
<ns2:gernes xmlns="http://www.w3.org/2001/XMLSchema/playlist" xmlns:ns2="https://xml.netbeans.org/schema/genses">
<ns2:gerne>
<GerneCode>1</GerneCode>
<GerneName>Pop</GerneName>
<Image>img-pop.jpg</Image>
</ns2:gerne>
</ns2:gerne>
I want to join these .xml files inside a XSL, to which will add the GerneName for every Song that match the GerneName inside the Gerne.xml.
The result im trying to get should be like this:
<Songs>
<Song>
<SongID>1</SongID>
<SongName>We dont talk anymore</SongName>
<Author>M-TP</Author>
<UploadBy>admin</UploadBy>
<GerneName>Pop</GerneName>
<GerneCode>1</GerneCode>
</Song>
</Songs>
Can anyone help me with this? Any e.g or keywords what should I look up for this problem?
Assuming you are limited to XSLT 1.0, you can do:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:pl="http://www.w3.org/2001/XMLSchema/playlist"
xmlns:ns2="https://xml.netbeans.org/schema/genses"
exclude-result-prefixes="pl ns2">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="lookup-path" select="'Gerne.xml'" />
<xsl:key name="genre" match="ns2:gerne" use="pl:GerneCode" />
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="GerneCode">
<xsl:variable name="code" select="." />
<!-- switch context to the other file -->
<xsl:for-each select="document($lookup-path)">
<GerneCode>
<xsl:value-of select="key('genre', $code)/pl:GerneName" />
</GerneCode>
</xsl:for-each>
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
This is assuming you are telling your XSLT processor to process the Song.xml file, and passing the path to the Gerne.xml file as a parameter.
Note that the Gerne.xml document you have posted is not well-formed XML (no </ns2:gernes> closing tag).
BTW, the correct term is "genre" - not "gerne" or "gense".
I have a number of Java classes that I am using in conjunction with JAXB in order to generate XML. The java classes have minimal changes from year to year but the output XML needs to have very specific yearly changes to it and it's proving a little elusive. I've tried updating the attributes using DOM but nodes further along the tree are maintaining the previous state. I've tried using reflection to update the annotations directly before marshalling but it doesn't seem to be having the desired effect. I've also tried replacing the XMLRootElement object (and XMLType, XMLElement) with local classes but nothing seems to be working properly as some information always seems to be retained somewhere even when it seems that I have changed the member/attribute/etc.
I am not going to duplicate all the java objects on a yearly basis just so that I can change the namespaces to match the requirements.
Right now I'm at the point where I think XSLT might be the last option but I have little to no knowledge of it. Is there a simple way to update 5-8 namespace URI's that are located on the root element? I don't want to change the prefixes (they are already set using a prefix mapper), I just want to change the namespace from "com.help.me.2014" to "com.help.me.2015".
Thanks
Andy
Resolution:
First off I greatly appreciate the effort and responses. I didn't actually try any of them as I came up with a different solution prior to getting back to see them.
Anyone coming along in the future can try the items listed below (as an XSLT solution) or you can try what I describe below.
I am generating XML in two different styles/formats, one with and one without SOAP wrappers. Due to my difficulty accessing the actual namespaces within the DOM/SOAP objects and my inability to alter the annotations at runtime I ended up capturing the output stream and manipulating the resulting string.
SOAP:
ByteArrayOutputStream stream = new ByteArrayOutputStream();
soapMessage.writeTo(stream);
String file = new String(stream.toByteArray);
... manipulate file (now a string), replace values, etc. -> actually passed to dependency injected converters, then send on to client via response.write
JAXB Marshalling is very similar to the SOAP, both send the resulting String onto converters which manipulate it as a StringBuilder then send it on.
Thanks again for the suggestions. Hopefully it helps someone in the future although the requirement is a little out there.
Andy
Changing namespaces every year is almost certainly the wrong thing to do, but the following XSLT stylesheet will change namespaces
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:old="oldspace"
version="1.0">
<xsl:template match="old:*">
<xsl:element name="{local-name(.)}" namespace="newspace">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="#old:*">
<xsl:attribute name="{local-name()}" namespace="newspace">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="*">
<xsl:copy select=".">
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="#*">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="processing-instruction()|comment()">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
This style sheet creates a copy of every element changing the namespace from oldspace to newspace when appropriate. Other than the namespace change, the original document is preserved. Similar templates can be made for every namespace that needs to be changed (note there are two templates that are namespace specific).
Note that prefixes WILL be altered. These are not really content as such, so it is nearly impossible to preserve them in a case like this. The only way I can think of to preserve those would involve writing a separate template for each element in the original, directly creating the new elements instead of using the xsl:element element.
For example, the given xml
<os:myroot xmlns:os="oldspace">
<?keep-this?>
<os:testing abc='3' def='9'>
<!-- This is a child -->
<os:item>1234</os:item>
</os:testing>
<!-- this element is in the default namespace -->
<testing2>
<abc>112233</abc>
</testing2>
</os:myroot>
is transformed to
<myroot xmlns="newspace">
<?keep-this?>
<testing>
<!-- This is a child -->
<item>1234</item>
</testing>
<!-- this element is in the default namespace -->
<testing2 xmlns="">
<abc>112233</abc>
</testing2>
</myroot>
where all elements that were in the oldspace namespace are now in the newspace namespace.
Here's an option that allows you to pass the old and new namespace URIs in as xsl:params.
XML Input (Borrowed from Matthew's answer; thanks!)
<os:myroot xmlns:os="com.help.me.2014">
<?keep-this?>
<os:testing abc='3' def='9'>
<!-- This is a child -->
<os:item>1234</os:item>
</os:testing>
<!-- this element is in the default namespace -->
<testing2>
<abc>112233</abc>
</testing2>
</os:myroot>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="oldns" select="'com.help.me.2014'"/>
<xsl:param name="newns" select="'com.help.me.2015'"/>
<xsl:template match="#*|node()" name="ident">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" priority="1">
<xsl:choose>
<xsl:when test="namespace-uri()=$oldns">
<xsl:element name="{name()}" namespace="{$newns}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
XML Output
<os:myroot xmlns:os="com.help.me.2015"><?keep-this?>
<os:testing abc="3" def="9"><!-- This is a child -->
<os:item>1234</os:item>
</os:testing><!-- this element is in the default namespace -->
<testing2>
<abc>112233</abc>
</testing2>
</os:myroot>
Here's an XSLT 2.0 option that produces the same output...
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="oldns" select="'com.help.me.2014'"/>
<xsl:param name="newns" select="'com.help.me.2015'"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" priority="1">
<xsl:element name="{name()}" namespace="{
if (namespace-uri()=$oldns) then $newns else namespace-uri()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Here's another 2.0 example that handles multiple namespace uris. The old and new uris are passed in as a string with commas as delimiters.
The order of the uris are important. The first old uri corresponds to the first new uri. The second old uri corresponds to the second new uri. Etc.
XML Input (updated to have more than one namespace uri)
<os:myroot xmlns:os="com.help.me.2014">
<?keep-this?>
<os:testing abc='3' def='9'>
<!-- This is a child -->
<os:item>1234</os:item>
</os:testing>
<!-- this element is in the default namespace -->
<testing2>
<abc>112233</abc>
</testing2>
<os2:testing xmlns:os2="com.help.me.again.2014">
<os2:item>ABCD</os2:item>
</os2:testing>
</os:myroot>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="oldns" select="'com.help.me.2014,com.help.me.again.2014'"/>
<xsl:param name="newns" select="'com.help.me.2015,com.help.me.again.2015'"/>
<xsl:variable name="oldns-seq" select="tokenize($oldns,',')"/>
<xsl:variable name="newns-seq" select="tokenize($newns,',')"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" priority="1">
<xsl:variable name="nsIdx" select="index-of($oldns-seq,namespace-uri())"/>
<xsl:element name="{name()}" namespace="{
if (namespace-uri()=$oldns-seq) then $newns-seq[$nsIdx] else namespace-uri()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
XML Output
<os:myroot xmlns:os="com.help.me.2015"><?keep-this?>
<os:testing abc="3" def="9"><!-- This is a child -->
<os:item>1234</os:item>
</os:testing>
<!-- this element is in the default namespace -->
<testing2>
<abc>112233</abc>
</testing2>
<os2:testing xmlns:os2="com.help.me.again.2015">
<os2:item>ABCD</os2:item>
</os2:testing>
</os:myroot>
I'm tring to transform an xsl:fo into xslt (for HTML output). Then, I would apply xslt instead of xsl:fo obtaining the HTML output instead of a PDF.
How can do this?
I need API for XML Processing, or JAXP that transforms XML and XSL to another output. So, I tried to write the xslt template:
<xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo"
>
<xsl:template match="/xsl:template[#match='/root']/fo:root">
<xsl:apply-templates select="fo:page-sequence"/>
</xsl:template>
<xsl:template match="fo:page-sequence">
<xsl:for-each select="fo:flow[#flow-name='xsl-region-body']">
<xsl:call-template name="xsl-regional-body">
<xsl:with-param name="fontsize"><xsl:value-of select="#font-size"/></xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="xsl-regional-body">
<xsl:param name="fontsize" />
<body>
<xsl:if test="$fontsize"> <!-- costruisce <font size=""> -->
<font>
<xsl:attribute name="size">
<xsl:value-of select="$fontsize"/>
</xsl:attribute>
</font>
</xsl:if>
<xsl:for-each select="*/xsl:choose">
<xsl:call-template name="xsl-choose"/>
</xsl:for-each>
<xsl:apply-templates select="."/>
</body>
</xsl:template>
<xsl:template name="xsl-choose">
<xsl:value-of select="."/>
</xsl:template>
I obtain something like
<body><font size="10pt"/>
...
text words..
</body>
But it delete all xsl:choose xsl:when and other tags like
I need all these tags because i need to pass xml data in second pass using Jaxp and producing html..
I would obtain
<body><font size="10pt"/>
<xsl:choose>
<xsl:when test="ddx[#id='LET.....>
<xsl::value-of select="ddx[#id='Lx']/r/PE...>
</xsl:when>..
</xsl:choose>
text words..
</body>
How can get the XSL nodes like text node?
If you want to use XSLT to output XSLT elements (i.e. elements in the XSLT namespace) then you need to use a namespace alias as shown in http://www.w3.org/TR/xslt#literal-result-element:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:template match="/">
<axsl:stylesheet>
<xsl:apply-templates/>
</axsl:stylesheet>
</xsl:template>
<xsl:template match="block">
<axsl:template match="{.}">
<fo:block><axsl:apply-templates/></fo:block>
</axsl:template>
</xsl:template>
</xsl:stylesheet>
i put xsl: code between < ! CDATA [... ] ] >
anyway using another namespace
I'm working on an XSLT that is giving me a little headache, and was looking for some tips. I'm working on converting an XML where some of the tags have namespaces prefixes, and others do not. I am working to convert all of the tags to one common namespace prefix.
Example of XML:
<yes:Books>
<no:Book>
<Title>Yes</Title>
<maybe:Version>1</maybe:Version>
</no:Book>
</yes:Books>
What I'm trying to get:
<yes:Books>
<yes:Book>
<yes:Title>Yes</yes:Title>
<yes:Version>1</yes:Version>
</yes:Book>
</yes:Books>
The XML input is the aggregate of several webservices, that are returning various namespaces. I have no issue aggregating it together appropriately, it's creating one common prefix namespace that I am having an issue with.
Worst case, I could regex them away, but I'm sure that isn't recomended.
Thanks.
This transformation allows the wanted final prefix and its namespace to be specified as external/global parameters. It shows how to process in the same way attribute names:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pPrefix" select="'yes'"/>
<xsl:param name="pNamespace" select="'yes'"/>
<xsl:template match="*">
<xsl:element name="{$pPrefix}:{local-name()}" namespace="{$pNamespace}">
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:attribute name="{$pPrefix}:{local-name()}" namespace="{$pNamespace}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
when applied on the following document (the provided one with one added attribute to make the problem more challenging):
<yes:Books xmlns:yes="yes">
<no:Book xmlns:no="no">
<Title no:Major="true">Yes</Title>
<maybe:Version xmlns:maybe="maybe">1</maybe:Version>
</no:Book>
</yes:Books>
produces the wanted, correct result:
<yes:Books xmlns:yes="yes">
<yes:Book>
<yes:Title yes:Major="true">Yes</yes:Title>
<yes:Version>1</yes:Version>
</yes:Book>
</yes:Books>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:custom="c">
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="custom:{local-name()}" namespace-uri="c">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>