I'm obtaining Swift MX messages and need to remove namespaces from them. In essence, they are two XML documents glued together. Most of the time they look like this:
<AppHdr>
contents of the header </AppHdr><Document>
contents of the document </Document>
This is easy to deal with as I put <root>
and </root>
around the whole thing to make XML (one root node only) and read it into an XmlDocument:
<root><AppHdr>
... </AppHdr><Document>
... </Document></root>
However, some of the messages have namespaces and the namespace is unknown at designtime. An example might be:
<ns2:AppHdr xmlns:ns2="some stuff">
contents of the header </ns2:AppHdr><ns3:Document xmlns:ns3="some other stuff">
contents of the document </ns3:Document>
Note that all of the XML tree under AppHdr
quote the namespace tag of AppHdr
and those under Document
quote that of Document
.
The namespace tags may vary. In this example they are ns2
and ns3
, but I don't know what they will be in advance. Is there an easy way to strip these out?
A minimal reproducible example is not provided. Here is a generic XSLT based solution that will work with any well-formed XML file.
Input XML
<root>
<ns2:AppHdr xmlns:ns2="some stuff">*contents of the header*</ns2:AppHdr>
<ns3:Document xmlns:ns3="some other stuff">*contents of the document*</ns3:Document>
</root>
XSLT
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<!-- template to copy elements -->
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<!-- template to copy attributes -->
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<!-- template to copy the rest of the nodes -->
<xsl:template match="comment() | text() | processing-instruction()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
Output XML
<root>
<AppHdr>*contents of the header*</AppHdr>
<Document>*contents of the document*</Document>
</root>
c#
void Main()
{
const string SOURCEXMLFILE = @"e:\Temp\input.xml";
const string XSLTFILE = @"e:\Temp\process.xslt";
const string OUTPUTXMLFILE = @"e:\temp\output.xml";
try
{
XsltArgumentList xslArg = new XsltArgumentList();
using (XmlReader src = XmlReader.Create(SOURCEXMLFILE))
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XSLTFILE, new XsltSettings(true, true), new XmlUrlResolver());
XmlWriterSettings settings = xslt.OutputSettings.Clone();
settings.IndentChars = "\t";
// to remove BOM
settings.Encoding = new UTF8Encoding(false);
using (XmlWriter result = XmlWriter.Create(OUTPUTXMLFILE, settings))
{
xslt.Transform(src, xslArg, result, new XmlUrlResolver());
result.Close();
}
}
Console.WriteLine("File '{0}' has been generated.", OUTPUTXMLFILE);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}