xml namespace issues when building an xml file in nodejs xmlbuilder2 - node.js

When I include this line in my template for nodejs xmlbuilder2:
template = {
'jcr:root': {
...
'#xmlns:jcr': 'http://www.jcp.org/jcr/1.0', // this one
...
}
}
I get the following error.
NamespaceError: The operation is not allowed by Namespaces in XML. [XMLNS] Qualified name includes a prefix but the namespace is null.
If I take it out, and paste "xmlns:jcr="..." in the xml file, and put it in AEM, it works (I should clarify, these are content fragments I'm making), but it does not show up in AEM without that line. I found this googling the error:
"if the qualified name includes a prefix, the namespace URI cannot be null or an empty string. if the reserved xmlns prefix is used, the namespace URI must match the corresponding specified system URI."
If I understand this right, my namespace URI is not null, and I am using xmlns:, so I need to change the uri to the right one? but this is the one that AEM has in its xml files when I download them.
I also think node doesn't like that 'xmlns:jcr' is an attribute of jcr:root, so it is defining jcr inside a jcr element, but again this is all copied verbatim from a file AEM made and I downloaded.

Related

No MessageBodyWriter for Single

I'm trying to use resteasy-rxjava2 to provide an XML document using jaxb, within a vertx application (using a non-vertx legacy library we have). But I get:
Could not find MessageBodyWriter for response object of type:
org.jboss.resteasy.rxjava2.propagation.ContextPropagatorOnSingleAssemblyAction$ContextPropagatorSingle of media type:
application/xml;charset=UTF-8
From what I can tell, this comes down to the difference between a MessageBodyWriter and the AsyncResponseProvider that is in the resteasy-rxjava2 dependency for a Single (SingleProvider).
I have the following resteasy service definition
#GET
#Path(FdsnwsPaths.QUERY)
#Produces(MediaType.APPLICATION_XML)
#Stream
// CHECKSTYLE:OFF too many parameters
public Response getQuery(...)
How do I get resteasy to properly serve the data asynchrously, using the SingleProvider or otherwise.
The #Get method must return the Single explicitly or it doesn't work. (Can't use Response or Object). In my case, the Single contains the jaxb xml root element.
#GET
#Path(FdsnwsPaths.QUERY)
#Produces(MediaType.APPLICATION_XML)
#Stream
public Single<FDSNStationXML> getQuery(...)
Then, to make things more complicated, in order to handle specific exception types and map them to specific response status codes, I have to create a custom ExceptionMapper which creates the Response object I used to be able to create directly in the method. (in resteasy-vertx, I found no documentation on how to do this, but in my case, I am creating my own VertxRestEasyDeployment object so I can register the class of the ExceptionMapper(s) like this:
VertxResteasyDeployment deployment = new VertxResteasyDeployment();
deployment.getActualProviderClasses().addAll(providerClasses);
For reference, this is all being done with:
RestEasy 5.0.3.Final (including resteasy-rxjava2)
RxJava 2.2.20
Vertx 3.9.5

Is there a way to register multiple namespaces using ElementTree

According to the docs, it seems like there can only be one namespace registered at a time.
xml.etree.ElementTree.register_namespace(prefix, uri)
Registers a namespace prefix. The registry is global, and any existing
mapping for either the given prefix or the namespace URI will be
removed. prefix is a namespace prefix. uri is a namespace uri.
Tags and attributes in this namespace will be serialized with the
given prefix, if at all possible.
But I was curious if anyone knows of some way around this? If there's nothing reasonable, I will switch to lxml.
You can register more than one namespace, just not in a single call to register_namespace().
You'd have to make separate calls to register_namespace() for each namespace.
Example...
import xml.etree.ElementTree as ET
ns_map = {"foo": "urn::foo",
"bar": "urn::bar"}
for prefix, uri in ns_map.items():
ET.register_namespace(prefix, uri)
root = ET.Element(ET.QName(ns_map["foo"], "root"))
ET.SubElement(root, ET.QName(ns_map["bar"], "child"))
print(ET.tostring(root).decode())
Prints...
<foo:root xmlns:bar="urn::bar" xmlns:foo="urn::foo"><bar:child /></foo:root>
Also...
If there's nothing reasonable, I will switch to lxml.
I'd switch to lxml anyway. :-)

JAXB: How to list identical child elements having different tags names

I have an XML in following format:
<servers>
<server_1>
<name>S1</name>
<user>User1</user>
<pass>pass1</pass>
</server_1>
<server_2>
<name>S2</name>
<user>User2</user>
<pass>pass2</pass>
</server_2>
<server_3>
<name>S3</name>
<user>User3</user>
<pass>pass3</pass>
</server_3>
</servers>
There can be multiple child elements under servers. And I am having trouble figuring out how to parse these using JAXB unmarshel. If the child would have identical name I could have just unmarshelled them into a list.
I also looked at #XMLAnyElement annotation which would allow me to have these elements into a list but I was facing some type cast issues since doing that gives ElementNSImpl and then I'd have to convert it to a simple Server entry class. Is that the only way to process such case?
Can't I use regex in #XMLElement's name field to populate such entries ignoring the different tags (server_1 , server_2 etc) or any other way to disregard the different child element tags.
I was using this guide to understand XMLAnyElement behavior: http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html but this is not really for my kind of use case.
Another approach I was thinking is of modifying the parent xml itself and replacing server_X type tags with server using Java FileReaders before unmarshling the XML file.
I will appreciate help or pointing me in right direction.
Edit: I see that following code works-
..
..
#XmlAnyElement
public List<ElementNSImpl> getServer() {
return server;
}
..
..
public void printElem() {
if(server!=null) {
for(ElementNSImpl serverEntry :server) {
NodeList nodeList= ftpEntry.getChildNodes();
System.out.println("length:"+nodeList.getLength());
for(int i=0;i<nodeList.getLength()-1;i++)
System.out.println(nodeList.item(i).getNodeName()+" :"+nodeList.item(i).getTextContent());
}
}
}
But java gives warning message on using ElementNSImpl directly:
Access restriction: The type 'ElementNSImpl' is not API (restriction on required library 'C:\Program Files (x86)\Java\jre1.8.0_171\lib\rt.jar')
So I am not sure if it is okay to use ElementNSImpl like this.

Botbuilder how to use default locale strings in case namespace hasn't defined it

I am using the botbuilder framework. I have defined several namespaces for the dialogs I have created, such as help or default. For all of these I have also created json files in my locale/en/ directory, and all is well.
However, I have a few sentences that are very common, and I don't feel like copying those over to each of the individual namespaces. I have tried using index.json as a 'fallback' in case the namespace file doesn't define the string. But it doesn't work for me. Contrary to what the documentation seems to suggest.
/locale
/en
/help.json
/default.json
/index.json <-- Doesn't work
/dialogs
/help.js
/default.js
bot.js
Say I have the following library in help.js, that :
lib = new builder.Library('help')
lib.dialog('/', (session) => {
session.send('custom_cancel')
}
module.exports = lib
The library is used in bot.js:
bot.library(require('./dialogs/help'))
And index.json has this content:
{
"custom_cancel": "My custom cancel"
}
Whereas help.json is empty:
{}
Because help.json does not have custom_cancel, the bot will actually send custom_cancel as the string.
Again. I can copy paste the strings to both locations and there is no more problem. But that seems like an ugly solution to me.
I have tried the more explicit version, which seems to help in more cases, but I am not fully convinced yet.
session.localizer.gettext(session.preferredLocale(), 'custom_cancel')
You can use the third argument for the namespace. It seems that '' will point to the index.json file.

JAXB Unable To Handle Attribute with Colon (:) in name?

I am attempting to use JAXB to unmarshall an XML files whose schema is defined by a DTD (ugh!).
The external provider of the DTD has specified one of the element attributes as xml:lang:
<!ATTLIST langSet
id ID #IMPLIED
xml:lang CDATA #REQUIRED
>
This comes into the xjc-generated class (standard generation; no *.xjb magic) as:
#XmlAttribute(name = "xml:lang", required = true)
#XmlJavaTypeAdapter(NormalizedStringAdapter.class)
protected String xmlLang;
However, when unmarshalling valid XML files with JAXB, the xmlLang attribute is always null.
When I edited the XML file, replacing xml:lang with lang and changed the #XmlAttribute to match, unmarshalling was successful (i.e. attributes were non-null).
I did find this http://old.nabble.com/unmarshalling-ignores-element-attribute-%27xml%27-td22558466.html. But, the resolution there was to convert to XML Schema, etc. My strong preference is to go straight from an un-altered DTD (since it is externally provided and defined by an ISO standard).
Is this a JAXB bug? Am I missing something about "namespaces" in attribute names?
FWIW, java -version = "build 1.6.0_20-b02" and xjc -version = "xjc version "JAXB 2.1.10 in JDK 6""
Solved the issue by changing replacing xml: with a namespace declaration in the JAXB-generated class:
#XmlAttribute(name = "lang", namespace="http://www.w3.org/XML/1998/namespace", required = true)
Which makes sense, in a way.
Without this kind of guidance, how would JAXB know how to interpret the otherwise-undefined namespace xml:? Unless, of course, it implemented some special-case internal handling to xml: as done in http://java.sun.com/javase/6/docs/api/javax/xml/stream/XMLStreamReader.html#getNamespaceURI%28java.lang.String%29 (see the first NOTE:)
Whether it's a bug in xjc's generation of the annotated objects or a bug in the unmarhaller, or simply requires a mapping somewhere in the xjc process is still an open question in my mind.
For now, it's working and all it requires is a little xjc magic, so I'm reasonably happy.
Disclaimer: Although 8 years late, I am adding this answer for lost souls such as myself trying to understand auto generation of java files from a DTD.
You can set project wide namespaces for the unmarshaller to work with directly in the project-info.java file via the #XmlSchema option.
This file should be automatically generated by xjc when generating classes from a schema, however it appears xjc does not automatically generate the package-info.java file when generating from a DTD!
However, you can manually make this file, and add it to the same package as the files generated by xjc.
The file would look like the following:
package-info.java :
#XmlSchema(
elementFormDefault=XmlNsForm.QUALIFIED,
xmlns = {
#XmlNs(prefix="xlink", namespaceURI="http://www.w3c.org/1999/xlink"),
#XmlNs(prefix="namespace2", namespaceURI="http://www.w3c.org/1999/namespace2")
})
package your.generated.package.hierarchy;
import javax.xml.bind.annotation.*;
You can add as many namespaces as required, simply add a new line in the form:
#XmlNs(prefix="namespace", namespaceURI="http://www.uri.to.namespace.com")
The benefit of doing it this way, rather than compared to editing the generated #XmlAttribute is that you do not need to change each generated XmlAttribute, and you do not need to manually remove the namespaces from the XmlAttribute name variable.

Resources