[XOM-interest] XSLTransform class API
dma_k at mail.ru
Fri Sep 17 07:11:22 EDT 2010
Again thank you for comments. I do appreciate them a lot.
On 17.09.2010 0:24, Elliotte Rusty Harold wrote:
> XOM is designed quite explicitly not to do everything in every
> possible way. I find that adding every possible variation of a given
> operation simply makes an API too confusing, hard to learn, and hard
> to use. New methods are added only if they have a compelling
> justification; i.e. if they add functionality that does not already
I agree with this statement. I have read your vision concerning XOM
library, your interview on  and also some chapters from you book "XML
in a nutshell"  (BTW, thank you for your work!). However, I would
like to express my opinion, which maybe will change XOM for better, if
you will also agree with me.
> There might be some justification for doing this, but it's not
> self-evident. The existing code does not reparse the document, and
> something's going to have to parse it at some point. You'd have to
> show there was a significant amount of overhead to building the XSL
> document as a XOM tree.
I fully agree on the statement that parsing the XSLT into XOM tree is
fast and should not be considered as memory or time loss at all. However
we can imagine, that I cannot receive the stylesheet neither as
InputStream, File or String. It is passed to me from some other 3rd
party library X as javax.xml.stream.XMLEventReader or as
org.xmlpull.v1.XmlPullParser. Of course, I agree that it is a bad
library X design (which should probably return commonly used
InputStream), but connecting it to XOM library becomes troublesome. I
would love to see all library APIs in world harmonized and following the
ground principles, but unfortunately, XOM API cannot change the world.
So it has to ways: either to ignore (and stay persistent) or to adapt.
>> * Having XOMResult/XOMSource classes public adds flexibility to XOM, as
>> one can use them separately from XSLTransform.
> No, you can't. The Source and Result interfaces are not properly
> designed for reuse. Not a lot I can do about that. For that matter,
> neither are XOMResult and XOMSource, but that's a deliberate decision
> and why they are private.
I read you message here as "(a) TrAX API is bad, that is why we (b)
should not support it and (c) suppress any attempts to add support for
it in XOM". I might agree with (a) and (b), but doing (c) frustrates me.
I personally think that "good API" also is "extendable API" (taken from
page 4 in Google presentation ), so if somebody inherits its class
from XSLTransform what is wrong with that? I agree that one can misuse
the parent XSLTransform class, break things and do a lot of harm, but if
I am to choose between "let people extend and re-use the classes and
*probably* make mistakes (and learn from them)" and "do not allow people
extend and re-use the classes (and get a headache)", I would choose the
first one. I have stressed the word *probably* because one needs to be a
real Java hacker to invent something to break XSLTransform class
functionality (maybe via reflection? byte-code injection?
>> * Returning Nodes as result of transformation is a bit odd (I took
>> extract from tutorial ):
>> Nodes output = transform.transform(input);
>> Document result = XSLTransform.toDocument(output);
>> I fully agree that result should be a list of nodes, but I think
>> returning DocumentFragment better matches the return result type. Maybe
>> it wouldn't be simple then...
> There is no DocumentFragment type in XOM. Why would you need it when
> you have Nodes?
There is nu.xom.DocumentFragment class, but it is (again) private. I try
to imagine what are the probable ways to use the result of
transformation. I think, in most cases applications serialize the result
of transformation into String/OutputStream/Writer (and send pipe it to
another module or application or DB). So I would expect to simply say:
String xml = transform.transform(input).toXML();
... and send String to next consumer in a pipe ...
So my points here:
1) If I use XSLTransform.toDocument(transform.transform(input)).toXML()
I get additionally post-transformed tree with first Element in root and
all other nodes as it's child. This post-transformation is not evident
and not natural but maybe OK for most transformations. I would like to
keep the original document as is after the transformation.
2) So I need to write a loop over all nodes and serialize them. Not a
big deal in general, but if API use case for almost all case is to loop
over all nodes, isn't it a signal to improve it? nu.xom.Serializer also
cannot write Nodes...
3) If transform() method returns DocumentFragment, I expect
DocumentFragment.toXML() not to break down in
UnsupportedOperationException, but correctly serialize all nodes in a
loop. Yes, in this case toXML() returns a non-complete (non-valid) XML,
but toXML() is not supposed to produce a valid XML, right? (e.g.
Text.toXML()). So the caller knows, what can be in output.
Also as we have touched the question of serialization, why
nu.xom.Serializer does not have a constructor with Writer? Internally it
uses a writer. The only added value I see in nu.xom.Serializer is to
protect the user from using broken EBCDIC-family output streams. If I
use broken JDK OutputStream implementation, I won't blame XOM, really.
And if I have only a Writer, I need to think how to convert it to
OutputStream for XOM, who will convert it to Writer :)
XOM provides a nice nu.xom.EBCDICWriter but again, it is not public.
This forces programmers to copy-paste the code, not not to re-use. Why
preventing it from being used even outside XOM?
Just for my information: can you please provide a reference for Sun JDK
bugtracker concerning EBCDIC problem. I would like to know for what JDK
is it relevant for. I tried to locate something relevant in , but I
Thank you a lot in advance for any comments.
With best regards,
More information about the XOM-interest