phobos icon indicating copy to clipboard operation
phobos copied to clipboard

Namespace prefix support

Open afleishaker opened this issue 3 years ago • 2 comments

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!

afleishaker avatar Sep 16 '22 13:09 afleishaker

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

valentiay avatar Sep 18 '22 14:09 valentiay

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!

afleishaker avatar Sep 19 '22 13:09 afleishaker

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

valentiay avatar Nov 13 '22 11:11 valentiay

I've implemented this feature in #252. I'll soon publish it in 0.18.0

valentiay avatar Nov 20 '22 10:11 valentiay