Matt wrote:
I have an XML document similar to the following:
<DataItems>
<Data xmlns="http://www.me.com">
<DataInformatio n xmlns:a="http://www.me.com/ASettings"
xsi:type="a:Stu ff1">
<a:Name>Matt</a:Name>
<a:TN>555-5555</a:TN>
</DataInformation >
</Data>
<Data xmlns="http://www.me.com">
<DataInformatio n xmlns:b="http://www.me.com/BSettings"
xsi:type="b:Stu ff2">
<b:Name>Bob</b:Name>
<b:TN>555-6666</b:TN>
</DataInformation >
</Data>
</DataItems>
What I would like to do is take all the namespaces and throw them in
the garbage! For example, I want to remove the xmlns attribute from
the Data node, I want to remove all the "a" and "b" prefixes from all
the nodes, etc. I want the final outcome to look like the following:
<DataItems>
<Data>
<DataInformatio n type="Stuff1">
<Name>Matt</Name>
<TN>555-5555</TN>
</DataInformation >
</Data>
<Data>
<DataInformatio n type="Stuff2">
<Name>Bob</Name>
<TN>555-6666</TN>
</DataInformation >
</Data>
</DataItems>
I am using C++ and Microsoft's xml implementation (DOM). I have no
choice but to use the raw Microsoft interfaces.
Does anyone have a good idea of how to do this?
XSLT is good for such tasks, the following stylesheet throws out all
namespace prefixes from element and attribute nodes:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:styleshe et version="1.0"
xmlns:xsl="http ://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" />
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@* | node()" />
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribut e name="{local-name()}"><xsl:v alue-of select="."
/></xsl:attribute>
</xsl:template>
<xsl:template match="text() | processing-instruction() | comment()">
<xsl:copy />
</xsl:template>
</xsl:stylesheet>
The transformation is done with a JavaScript and MSXML 4 as follows (I
know you asked about C++ but I have never used MSXML with C++ thus I
hope you will be able to translate the JavaScript into C++):
var sourceDocument = new ActiveXObject(' Msxml2.DOMDocum ent.4.0');
sourceDocument. async = false;
sourceDocument. preserveWhiteSp ace = true;
sourceDocument. validateOnParse = false;
var loaded = sourceDocument. load('test20040 408.xml');
if (loaded) {
var xslDocument = new ActiveXObject(' Msxml2.DOMDocum ent.4.0');
xslDocument.asy nc = false;
loaded = xslDocument.loa d('test20040408 Xsl.xml');
if (loaded) {
var resultDocument = new ActiveXObject(' Msxml2.DOMDocum ent.4.0');
sourceDocument. transformNodeTo Object(xslDocum ent, resultDocument) ;
resultDocument. save('whatever. xml');
}
}
While I tested I have seen that the transformtion is not quite doing
what you want as you also seem to want to remove any "prefixes" in
attribute values so you need to change the stylesheet to use the
following template for attribute nodes:
<xsl:template match="@*">
<xsl:attribut e name="{local-name()}">
<xsl:choose>
<xsl:when test="contains( ., ':')">
<xsl:value-of select="substri ng-after(., ':')" />
</xsl:when>
<xsl:otherwis e>
<xsl:value-of select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
--
Martin Honnen
http://JavaScript.FAQTs.com/