xml-js icon indicating copy to clipboard operation
xml-js copied to clipboard

Always prefix elements with namespace

Open ultimate-tester opened this issue 6 years ago • 9 comments

Hi there, I have a use case where the XML is not fixed, it can be anything according to a certain spec. At the moment I am looking for a specific property, let's take the following examples:

<d:multistatus xmlns="DAV:">
	<response>
		<href>/</href>
		    <propstat>
			    <prop>
					<current-user-principal>
						<href>/principals/users/johndoe/</href>
					</current-user-principal>
			    </prop>
			<status>HTTP/1.1 200 OK</status>
		</propstat>
	</response>
</d:multistatus>
<d:multistatus xmlns:d="DAV:">
    <d:response>
        <d:href>/</d:href>
        <d:propstat>
            <d:prop>
                <d:current-user-principal>
                    <d:href>/principals/users/johndoe/</d:href>
                </d:current-user-principal>
            </d:prop>
            <d:status>HTTP/1.1 200 OK</d:status>
        </d:propstat>
    </d:response>
</d:multistatus>

You see one time I get the XML with a global namespace defined to "DAV:" making all elements part of that namespace and the other time theres a namespace of "d" that maps the "d:" to "DAV:".

When I check the JSON object for existence of "d:multistatus", it will return false on the first part of xml while there actually is a "multistatus" element. What I would like to see is that every element in the XML is prefixed by the namespace. So that in both above cases, the elements are called "DAV:multistatus" instead of "d:multistatus" or just "multistatus".

I hope you know what I mean, and can help me with this problem. Maybe there is already a way to get the elements correctly respecting the namespaces.. I'd like to hear from you :)

ultimate-tester avatar Dec 12 '17 16:12 ultimate-tester

I am not sure if I understand the issue correctly. Are you facing the problem when converting from xml → json or from json → xml? Or is it from xml→json→xml?

Or is the xml input changing sometimes so the elements get prepended with d: namespace?

I really would like to help you overcoming the issue you are facing, but can you clarify more whether this library is not doing conversion as per your expectation or you are looking for a new feature to be implemented to support your use case?

nashwaan avatar Dec 12 '17 17:12 nashwaan

I’m sure there is nothing wrong with xml-js in this matter, I’m looking for a (new) feature.

I have the given xml snippets. Using xml-is I convert them to json. Now, because the xml snippets originate from different systems, the output differs in a way where the namespaces are either of a different name or mapped to the global xml namespace. When traversing and checking for specific elements, my check for (for instance) “d:multiresponse” will return false when the namespace was not mapped to “d” but to the global namespace (making every element part of that namespace).

Now comes what I want to see to overcome this problem: if all elements are simply fully classified (e.g. with an element named d:multiresponse, the parser will resolve “d” to the correct namespace, which is “dav” in this case making the final element in the json to be named “dav:multiresponse”). That way it will be much easier to parse elements from xml that comes from different sources where people chose to name/map a namespace to a different name. I hope this explains it enough. If needed I will make a graphic that explains what I want to accomplish.


From: Yousuf [email protected] Sent: Tuesday, December 12, 2017 6:23:19 PM To: nashwaan/xml-js Cc: ultimate-tester; Author Subject: Re: [nashwaan/xml-js] Always prefix elements with namespace (#41)

I am not sure if I understand the issue correctly. Are you facing the problem when converting from xml → json or from json → xml? Or is it from xml→json→xml?

Or is the xml input changing sometimes so the elements get prepended with d: namespace?

I really would like to help you overcoming the issue you are facing, but can you clarify more whether this library is not doing conversion as per your expectation or you are looking for a new feature to be implemented to support your use case?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/nashwaan/xml-js/issues/41#issuecomment-351122510, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AAjclo687dy5NAEf0w3dPwhZ3_eOkZLBks5s_raHgaJpZM4Q_NUJ.

ultimate-tester avatar Dec 12 '17 18:12 ultimate-tester

Here is my understanding of the problem:

sample1.xml:

<d:foo xmlns="DAV:">
    <bar>something</bar>
</d:foo>

converting sample1.xml using convert.xml2js(sample1, {compact: true}) results (using compact form for the sake of brevity):

{
  "d:foo": {
    "_attributes": {
      "xmlns": "DAV:"
    },
    "bar": {
      "_text": "something"
    }
  }
}

sample2.xml:

<d:foo xmlns:d="DAV:">
    <d:bar>something</d:bar>
</d:foo>

converting sample2.xml using convert.xml2js(sample2, {compact: true}) results:

{
  "d:foo": {
    "_attributes": {
      "d:xmlns": "DAV:"
    },
    "d:bar": {
      "_text": "something"
    }
  }
}

But, what you want is to have the following output for both sample1.xml and sample2.xml:

{
  "d:foo": {
    "_attributes": {
      "d:xmlns": "DAV:"
    },
    "DAV:bar": {
      "_text": "something"
    }
  }
}

If this is what you want, then a new option, say {resolveNamespace: true}, should be implemented to support this scenario. Is my understanding correct?

nashwaan avatar Dec 13 '17 04:12 nashwaan

Absoluty! I could try to have a look at it because it sounds kind of easy but I’m sure I’m thinking too little of it. Please let me know if you’ll accept pull request for this :)


From: Yousuf [email protected] Sent: Wednesday, December 13, 2017 5:53:42 AM To: nashwaan/xml-js Cc: ultimate-tester; Author Subject: Re: [nashwaan/xml-js] Always prefix elements with namespace (#41)

Here is my understanding of the problem:

sample1.xml:

<d:foo xmlns="DAV:"> something </d:foo>

converting sample1.xml using convert.xml2js(sample1, {compact: true}) results (using compact form for the sake of brevity):

{ "d:foo": { "_attributes": { "xmlns": "DAV:" }, "bar": { "_text": "something" } } }


sample2.xml:

<d:foo xmlns:d="DAV:"> <d:bar>something</d:bar> </d:foo>

converting sample2.xml using convert.xml2js(sample2, {compact: true}) results:

{ "d:foo": { "_attributes": { "d:xmlns": "DAV:" }, "d:bar": { "_text": "something" } } }


But, what you want is to have the following output for both sample1.xml and sample2.xml:

{ "d:foo": { "_attributes": { "d:xmlns": "DAV:" }, "DAV:bar": { "_text": "something" } } }

If this is what you want, then a new option, say {resolveNamespace: true}, should be implemented to support this scenario. Is my understanding correct?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/nashwaan/xml-js/issues/41#issuecomment-351282158, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AAjclho_w9OUI5yaAtvnDFcupY3osqTfks5s_1hWgaJpZM4Q_NUJ.

ultimate-tester avatar Dec 13 '17 06:12 ultimate-tester

I certainly would accept pull requests, but not at the moment. Right now I am working on adding a major feature to the library: the ability to supply callback functions as additional processing to names, values, attributes, ...etc. Which can partly help to solve your problem like this:

function addPrefix(name) {
  return 'DAV:' + name.substring(name.indexOf(":") + 1);
}

convert.xml2js(sample1, {compact: true, elementNameFn: addPrefix})
convert.xml2js(sample2, {compact: true, elementNameFn: addPrefix})

But it will generate the following result (notice DAV:foo which is not what you want):

{
  "DAV:foo": {
    "_attributes": {
      "d:xmlns": "DAV:"
    },
    "DAV:bar": {
      "_text": "something"
    }
  }
}

This might not be a clean solution to deal with namespace, but I think it will help for other cases.

Just give me couple of days until I finish releasing it, and then you can attempt to add this feature {resolveNamespace: true} if you want. I think another complementary option {stripNamespace: true} is also needed to remove namespace prefix.

nashwaan avatar Dec 13 '17 06:12 nashwaan

Although I thank you for your effort, I guess we might run into an issue here for people with an other use case than mine.

I just looked at the spec (https://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-decl), where it clearly reads that originally namespaces are bound to URI's. Resolving those namespaces (d: to an URI) wouldn't make sense and the element names will get very long (or is that no problem at all?)

Removing the namespaces also gives conflicts. It's perfectly acceptable to have an element of d:foo and also e:foo. They are both called foo but are from different namespaces making them effectively a different element. Removing the namespaces will result in the elements becoming of the same namespaces which will give trouble when you are converting back to XML (from XML -> JSON -> XML).

Lastly, to remember: The element in which a namespace is defined, can also prefix the element with that namespace and be valid, as the example in the spec shows:

<x xmlns:edi='http://ecommerce.org/schema'>
  <!-- the "edi" prefix is bound to http://ecommerce.org/schema
       for the "x" element and contents -->
</x>

Meaning the first line in the xml (the x element) could also have been edi:x instead of x, but that's something for later!

ultimate-tester avatar Dec 13 '17 07:12 ultimate-tester

Hi @ultimate-tester, sorry for late response. Just published v1.6.0 of this library which now supports adding custom functions for additional processing. Using elementNameFn should work now.

To solve namespace issue properly, we need to implement {resolveNamespace: true}. I am not familiar with namespace thing and I need to spend some time learning it. But if you are willing to contribute, then feel free to submit a pull request as I have completed adding Custom functions feature. I will try to accommodate your changes as soon as I can. Thanks.

nashwaan avatar Dec 17 '17 11:12 nashwaan

Any update on this?

{resolveNamespace: true}

sounds great!

Lonzak avatar May 05 '22 10:05 Lonzak

Close to 6 years later and the XML library with still no namespace support ...

loganmzz avatar Sep 26 '23 06:09 loganmzz