XML Transformer

I’m sorry for my english. I meant class inheritance structure by saying “tree structure”. I solved my problem by using the property InheritFromXmlTransformer (I’m not sure I remember it correctly).

Usually the only reason to use the GoXmlTransformer.InheritsFromTransformer property is when you want to modify the behavior of an existing transformer for a given Type and you cannot define a subclass of that GoXmlTransformer.
If you can define a subclass of a particular transformer class, then you can override methods. Typically you will call the base method as well as adding whatever code you needed, but you might need to completely replace the implementation of a method (if you didn’t want the super class’s behavior).

I’ve tried this but got the output I showed in the first post. You can see there are duplicated attributes and elements with exactly the same values.

For example, I have a class MyRoot derived from GoGeneralNode. I define a transformer class MyRootTransformer derived from GoXmlTransformer to save MyRoot to XML. I have another class MySub derived from MyRoot, and a transformer class MySubTransformer derived from MyRootTransformer to save MySub to XML. To make things simple, in the MySubTransformer I only define a constructor in which I set the element type. All other methods are inherited from MyRootTransformer.

If I add MyRootTransformer and MySubTransformer into the writer, I will get duplicated attributes and elements.

Yes, that makes sense now. Let’s just focus on writing out attributes, for example. You have two transformers (i.e. one instance each of two transformer classes) which do basically exactly the same thing. One is associated with MyRoot, the other with MySub.
If your document just has instances of MyRoot, I assume everything works fine, right? It’s only instances of MySub in your diagram that get duplicated attributes in the generated XML, yes?
That’s because for instances of MySub both MySubTransformer.GenerateAttributes is being called and MyRootTransformer.GenerateAttributes. The way you have defined it, MySubTransformer.GenerateAttributes is just calling MyRootTransformer.GenerateAttributes. So MyRootTransformer.GenerateAttributes is being called twice – hence the duplicated attributes.
If you aren’t overriding methods of MyRootTransformer in order to do something different, or in order to access protected transformer methods, you shouldn’t be inheriting from MyRootTransformer, but from GoXmlTransformer. Certainly if you just want to add some attributes for MySub you should just inherit from GoXmlTransformer.
But if you do want to define MySubTransformer inheriting from MyRootTransformer, that’s OK – just don’t call the base method if you want to add some functionality beyond that which MyRootTransformer provides.

[QUOTE=walter]

If your document just has instances of MyRoot, I assume everything works fine, right? It’s only instances of MySub in your diagram that get duplicated attributes in the generated XML, yes?

[/quote]

Yes, you are right here. Only XML for MySub gets duplicated attributes and duplicated elements for GoPort as well.

[QUOTE=walter]

That's because for instances of MySub both MySubTransformer.GenerateAttributes is being called and MyRootTransformer.GenerateAttributes.

[/quote]

To me, this should not be the way. GoDiagram should save object using the Xml transformer with its TransformerType equal to the object's type, shouldn't it?

[QUOTE=walter]

The way you have defined it, MySubTransformer.GenerateAttributes is just calling MyRootTransformer.GenerateAttributes.

[/quote]

This was my intention.

[QUOTE=walter]

So MyRootTransformer.GenerateAttributes is being called twice -- hence the duplicated attributes.

If you aren't overriding methods of MyRootTransformer in order to do something different, or in order to access protected transformer methods, you shouldn't be inheriting from MyRootTransformer, but from GoXmlTransformer. Certainly if you just want to add some attributes for MySub you should just inherit from GoXmlTransformer.

But if you do want to define MySubTransformer inheriting from MyRootTransformer, that's OK -- just don't call the base method if you want to add some functionality beyond that which MyRootTransformer provides.[/quote]

OK, using InheritFromXmlTransfomer is a solution, and overriding methods doing nothing is another solution. But it seems conflicting to the common knowledge of inheritance, just because of the way GoDiagram uses Xml transformers.

If GoDiagram simply have used Xml transformers with TransformerType equal to the object type, there would be no such problems.

Yes, the model you describe is another way to design this kind of functionality.
However, that kind of design is not as flexible, since if you want to modify or replace the functionality for a base class of the GoObjects being traversed, there is no practical way to do so.
For example, let’s say your application has several different node classes. You’ll probably define several corresponding transformers inheriting from GoXmlTransformer. So how would you change the behavior for all nodes? With the published design, it’s easy to add an attribute or two for all nodes classes just by defining (or replacing if one already exists) the transformer for the GoNode class.