I think I have found a few bugs in MessageElement. Either that or I need an explanation on how things work. I am building up a SOAPEnvelope using MessageElement's. When I build the MessageElement, I set the name, attributes, value, etc. One specific attribute I set is the xsi:type. Obviously this is an important attribute. And the problem revolves around that this attribute is set to a qualified name.
First I tried to use setType, but this does not seem to work. If I use setType and then call getType, it gets the right thing, but it does not add it to the attributes when toString is called. I looked through the output method (which seems to handle serializing MessageElements into Strings) and it does not appear that the type is ever added to the attributes or set in any other way. So when output is called, the type is not added (that I can see). Here is an example... MessageElement element = new MessageElement(); element.setName(<name>); element.setNamespaceURI(<ns>); element.setType(new QName(<ns>,<localpart>)); System.out.println(element.toString()); Here is what probably should be done in the outputImpl method of MessageElement... context.serialize(new QName(namespaceURI, name), attributes, objectValue, typeQName, false, Boolean.TRUE); rather than... context.serialize(new QName(namespaceURI, name), attributes, objectValue, null, false, Boolean.TRUE); So since the above didn't work I tried to add an attribute for it manually. At first I tried to use addAttribute(ns, local, qname). This adds the attribute, and when you call it the first time, it works properly. It adds the namespace declaration and the attribute. However, on subsequent calls, it does not work, because it appears that the the namespace declaration is added to the SerializationContext rather than to the MessageElemnt Attributes. Here is an example... MessageElement element = new MessageElement(); element.setName(<name>); element.setNamespaceURI(<ns>); element@addAttribute("http://www.w3.org/2001/XMLSchema-instance","type", new QName(<ns>, <localName>)); System.out.println(element.toString()); System.out.println(element.toString()); Here is the place in MessageElement that is useful... if (qNameAttrs != null) { for (int i = 0; i < qNameAttrs.size(); i++) { QNameAttr attr = (QNameAttr)qNameAttrs.get(i); QName attrName = attr.name; System.out.println("Attr.value: " + context.qName2String(attr.value)); addAttribute(attrName.getNamespaceURI(), attrName.getLocalPart(), context.qName2String(attr.value)); } qNameAttrs = null; } The key to this is the call to qName2String. If you bounce around a bit inside SerializationContext you will see that if the namespace does not exist, it will create a new one and register it with the SerializationContext, but not add it as an attibute or anything to the MessageElement. Then the qNameAttrs are set to null and that namespace declaration is officially lost after leaving the SerializationContext. The namespace is not written back as an attribute, as the prefixed attribute is above. Perhaps the qName2String method should be in MessageElement. But regardless how you do it, those namespace declarations need to be persisted past the SerializationContext. Next I tried to add the type attribute a different way. This time I decided I would keep track of the namespace prefixes myself and add elements based on my prefixes. I added the type definition with element.addAttribute("http://www.w3.org/2001/XMLSchema-instance", "type", <prefix> + <localPart>). Then I planned on adding the namespace declaration with element.addNamespaceDeclaration(<prefix>, <namespaceURI). For this the first call is executed correctly, but the second call has problems. The namespace declarations are never added as attributes. Here is an example... MessageElement element = new MessageElement(); element.setName(<name>); element.setNamespaceURI(<ns>); element.addAttribute("http://www.w3.org/2001/XMLSchema-instance", "type", <prefix> + ":" + <localpart>); element.addNamespaceDeclaration(<prefix>, <namespaceURI>); System.out.println(element.toString()); Here is what probably should be done in the outputImpl method of MessageElement... context.serialize(new QName(namespaceURI, name), getCompleteAttributes(), objectValue, null, false, Boolean.TRUE); rather than... context.serialize(new QName(namespaceURI, name), attributes, objectValue, null, false, Boolean.TRUE); Finally since I could not add a namespace declaration using the method, I tried to do it by adding an attribute. I used the addAttribute(new PrefixedQName(Constants`NS_URI_XMLNS, prefix, "xmlns"), <namespaceURI>); However, this adds a new namespace declaration for xmlns which I do not want. And then it prefixes the attribute I am declaring with something besides "xmlns". This doesn't work. There is not a good way to add namespace declarations manually. When you guys implement getCompleteAttributes you use have access to the prefix parameter of the addAttribute method from Attributes, but that parameter not available in the addAttribute signature of MessageElement. Here is an example... MessageElement element = new MessageElement(); element.setName(<name>); element.addAttribute(new PrefixedQName(Constants`NS_URI_XMLNS, prefix, "xmlns"), <namespaceURI>); element.addAttribute("http://www.w3.org/2001/XMLSchema-instance", "type", <prefix> + ":" + <localpart>); element.addNamespaceDeclaration(<prefix>, <namespaceURI>); System.out.println(element.toString()); Please take a look at these problems with MessageElement and let me know if I am way off base. I would like to report these as bugs if they truly are. They are important bugs to me. It makes my application completely unusable at the moment. Chris Williamson