I have a large database XML file with defaultnamespace to be transformed using XSLT. Here is a minimal example.
The file is called server.xml. It contains incorrect data.
<?xml version="1.0" encoding="UTF-8"?>
<bookstore xmlns="http://www.mybook.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<book author="Incorrect_Author">
<title>Correct_Title</title>
</book>
</bookstore>
The author needs to be changed to the correct value by matching the title of the book in another XML file.
This second xml file is called client.xml. It contains the correct author name for the book.
<?xml version="1.0" encoding="UTF-8"?>
<bookstore xmlns="http://www.mybook.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<book author="Correct_Author">
<title>Correct_Title</title>
<additionalstuff/>
</book>
</bookstore>
However, it also has additional info I don't want. So I want to modify server based on client, matching by book title.
I have written the following XSLT (based on this answer). It works to do the job if I artificially remove the default xmlns in my xml files.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="clientXml" select="'client.xml'" />
<xsl:variable name="client" select="document($clientXml)//book" />
<xsl:template match="book/@author">
<xsl:attribute name="author">
<xsl:value-of select="$client[child::title=current()/../title]/@author" />
</xsl:attribute>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
However, I need this to work with the files as they are (containing the default ns). I know this is a current question, so I have tried the following code based on answers I found. It doesn't work. Is it a problem with the XPath prefixing?
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:v="http://www.mybook.com" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="v" >
<xsl:output method="xml" indent="yes"/>
<xsl:param name="clientXml" select="'client.xml'" />
<xsl:variable name="client" select="document($clientXml)//v:book" />
<xsl:template match="v:book/@author">
<xsl:attribute name="author">
<xsl:value-of select="$client[child::title=current()/../title]/@author" />
</xsl:attribute>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>