Namespace prefix support
Hi there,
I was looking to set up namespaces with a given prefix instead of being automatically determined as ans\d+ in PhobosStreamWriter.
Example of ideal output sampled from w3schools:
<f:table xmlns:f="https://www.w3schools.com/furniture">
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
where right now from my understanding I wouldn't be able to define the f prefix.
Am I correct in this understanding? If so, is there any straightforward way to accomplish this or work around it if not? Thanks for your insight!
Hi!
You're right. It's currently impossible to define specific namespace prefix.
According to the XML namespaces specification
... the namespace prefix, used to associate element and attribute names with the namespace name in the attribute value in the scope of the element to which the declaration is attached
The Prefix provides the namespace prefix part of the qualified name, and MUST be associated with a namespace URI reference in a namespace declaration
the prefix is only a reference to the specific namespace name (URI). The prefix name doesn't really matter. So, three XML documents below are identical from structural point of view:
<f:table xmlns:f="https://www.w3schools.com/furniture">
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
<ans1:table xmlns:ans1="https://www.w3schools.com/furniture">
<!-- Different prefix name, same URI -->
<ans1:name>African Coffee Table</ans1:name>
<ans1:width>80</ans1:width>
<ans1:length>120</ans1:length>
</ans1:table>
<table xmlns="https://www.w3schools.com/furniture">
<!-- No prefix at all, default namespace has the same URI -->
<name>African Coffee Table</name>
<width>80</width>
<length>120</length>
</table>
I'll research, how can I implement the capability to configure prefix. If It's not too complex (it shouldn't be) I'll add this feature in the next release. This still could be useful for aesthetic and readability, or for integrating with poorly written XML processors
Hi @valentiay , thanks for your prompt response!
I played around locally with changing the writeStartElement method invoked to be the prefix one here: https://github.com/Tinkoff/phobos/blob/9ca34a9fa2679b1a9d25c13de6cac0db3bf19b65/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/PhobosStreamWriter.scala#L202
Doing so in both EncoderDerivation and ElementEncoder's stringEncoder on namespace fold: https://github.com/Tinkoff/phobos/blob/7a5724a92e1f381692167306dbd8da28f311b500/modules/core/src/main/scala-2/ru/tinkoff/phobos/derivation/EncoderDerivation.scala#L138 https://github.com/Tinkoff/phobos/blob/7a5724a92e1f381692167306dbd8da28f311b500/modules/core/src/main/scala/ru/tinkoff/phobos/encoding/ElementEncoder.scala#L40
This appeared to work, manually overriding it with canned prefixes.
But I wasn't sure based on your impl of Namespace how you would want to approach passing a user-defined prefix, etc, so I didn't attempt a PR.
Hope that this isn't too much of a lift if it's beneficial and thanks for giving me the insight!
Hi! Excuse me for long absence. I think, that this would be a great feature, I'll try to implement it next week. I have an idea, how it should look. Preferred namespace prefixes should be defined (or derived from object name) in namespace object declaration:
@XmlnsDef("http://example.org/schema1")
case object sch1 // preferred prefix is sch1
case object sch2
Namespace.mkInstance("http://example.org/schema2", "sch2") // preferred prefix is sch2
These prefixes then will be passed to ElementEncoder, and there they will be passed to StreamWriter.writeStartElement
I've implemented this feature in #252. I'll soon publish it in 0.18.0