views:

65

answers:

1

I am using MSXML 6.0 to perform a transform of my own XML into another XML format. I am not sure if I maybe just don't understand exactly how MSXML works, but I believe I have noticed some strange behaviour with it....

I am adding in the namespaces to my XML doc using the setProperty method e.g.

XmlDocument.setProperty('SelectionNamespaces',
' xmlns:ms=''http://mydomain.com/2010/MySchema''');

Then I am building up the XML using my own custom serializer in memory (not saving to disk). Once serialized I then load in the XSLT file and perform the transformation using transformNodeToObject e.g.

AppXmlDoc.transformNodeToObject(XslXmlDoc, AStreamForTransformedXml);

The problem is the transform is working but none of the specific template matching XPath I have in it is. I eliminated any problems with the XSLT file itself by running it with test data through Visual Studio and it worked as expected. I then assumed it must have been an encoding issue so I made sure that all the documents involved were being read/written out as UTF-8....still no luck.

Here is an example of what the transform looks like:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ms="http://mydomain.com/2010/MySchema" exclude-result-prefixes="ms">
<xsl:template match="/">
<ARoot>      
  <head>
    <xsl:apply-templates select="ms:Element/ms:SubElement" />
  </head>
  <body>
    <xsl:apply-templates select="ms:Element/ms:DifferentSubElement" />
  </body>
</ARoot>

So the result of the transform when run through MSXML brings over the basic structure but does not include any of the template data. After some testing I discovered the only way to get it to work is to do it in the following steps:

  1. Create a new XML doc
  2. Set the namespace info using setProperty
  3. Serialize the XML and save to disk.
  4. Close the document - extra step
  5. Create a new Xml doc - extra step
  6. Reload the document - extra step
  7. Re-set the namespace info - extra step
  8. Perform the transform.

So it appears that MSXML loses track of the Namespace information at somepoint. What makes it even more weird is even if you reset the namespace info (after serializing) and try the transform it still doesn't work! It will only seem to work if I save the document, close it and recreate a new XML document and load it back in (which as a consequence I need to reset the namespaces).

Anyone have any thoughts/ideas on this?

+1  A: 

The SelectionNamespace property is used for XPath with the selectNodes and selectSingleNode methods, not for XSLT or other purposes. So I am not sure why you set it and what you expect it to help with as you do not seem to use selectNodes or selectSingleNode. What is it that you want to achieve with MSXML 6? If you want to create some MSXML DOM documents with elements and/or attributes in namespaces then make sure you use createNode as that is the only namespace aware method in MSXML's API.

Martin Honnen
I have my own custom XML which has it's own schema. When I write my XML format out my element names will contain the prefix of my schema e.g. `ms:Element`. So for the XML document to be valid it *must* contain the namespaces. As for the XSLT containing it....if I don't specify the namespace when I do the XPath then it doesn't match anything.
James
I didn't quite understand what you were referring to at first. After some refactoring of my code I understand where I was going wrong. When I was creating nodes using `createElement`/`createAttribute` this is namespace-ignorant i.e. those nodes will not be mapped against any specific namespace. Changing my serializer to use `createNode` as you suggested did the trick. Thanks.
James