<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<br>
<br>
<div class="moz-cite-prefix">On 10/5/15 4:25 PM, Camel Guy wrote:<br>
</div>
<blockquote
cite="mid:CAJtt6BhCMd0G1joZJuQEY0XqpH+NDPYKb4C7q1L=+PqyW09inA@mail.gmail.com"
type="cite">
<div dir="ltr"><br>
<div><br>
</div>
<div>
<div>My document looks like:</div>
<div><br>
</div>
<div><n:attributes xmlns:n='foo'><br>
<n:attribute n:name='AcctId' n:value='000004D' /><br>
</n:attributes></div>
<div><br>
</div>
</div>
</div>
</blockquote>
<br>
That's fine. Since it's not a known, supported schema, you'll need
to change things up slightly from the basic XMLObjectSupport
example.<br>
<br>
<blockquote
cite="mid:CAJtt6BhCMd0G1joZJuQEY0XqpH+NDPYKb4C7q1L=+PqyW09inA@mail.gmail.com"
type="cite">
<div dir="ltr">
<div>
<div>This is just a sample document. I put everything in a
namespace to try to work around the error I've run into
(read on..).</div>
</div>
<div><br>
</div>
</div>
</blockquote>
<br>
Since it's going into a namespace-qualified XML environment (SAML),
it pretty much has to be namespace-qualified XML. Mixing the two
doesn't work very well.<br>
<br>
<br>
<blockquote
cite="mid:CAJtt6BhCMd0G1joZJuQEY0XqpH+NDPYKb4C7q1L=+PqyW09inA@mail.gmail.com"
type="cite">
<div dir="ltr"><br>
<div>I'm getting the same error as described in</div>
<div><a moz-do-not-send="true"
href="http://shibboleth.net/pipermail/users/2015-July/022646.html">http://shibboleth.net/pipermail/users/2015-July/022646.html</a></div>
<div><br>
</div>
</div>
</blockquote>
<br>
Ooops. I was on vacation then, and looks like neither I nor anyone
else responded. Hopefully if
<meta http-equiv="content-type" content="text/html;
charset=windows-1252">
<meta http-equiv="content-type" content="text/html;
charset=windows-1252">
Alessio is still on the list, he'll accept my belated apology for
missing his post.<br>
<br>
<br>
<blockquote
cite="mid:CAJtt6BhCMd0G1joZJuQEY0XqpH+NDPYKb4C7q1L=+PqyW09inA@mail.gmail.com"
type="cite">
<div dir="ltr">
<div>A bit of the stack trace:</div>
<div>
<div>
<p class="">net.shibboleth.utilities.java.support.logic.ConstraintViolationException:
Local name cannot be null or empty<br>
at
net.shibboleth.utilities.java.support.logic.Constraint.isNotNull(Constraint.java:227)
~[java-support-7.1.1.jar:na]<br>
at
net.shibboleth.utilities.java.support.xml.QNameSupport.constructQName(QNameSupport.java:79)
~[java-support-7.1.1.jar:na]<br>
at
net.shibboleth.utilities.java.support.xml.QNameSupport.getNodeQName(QNameSupport.java:102)
~[java-support-7.1.1.jar:na]<br>
at
org.opensaml.core.xml.io.UnmarshallerFactory.getUnmarshaller(UnmarshallerFactory.java:86)
~[opensaml-core-3.1.1.jar:na]<br>
at
org.opensaml.core.xml.io.UnmarshallerFactory$getUnmarshaller.call(Unknown
Source) ~[na:na]</p>
</div>
</div>
</div>
</blockquote>
<br>
<br>
Well, that error is happening because: The XML is
namespace-qualified, but you haven't set the 'namespaceAware'
property on the DocumentBuilderFactory to 'true'. So it's not
parsing in a namespace-aware way. That is mandatory to do in this
case. It's nothing to do with Shibboleth/OpenSAML. You have to set
that if you're going to parse namespace-qualified XML with a JAXP
DocumentBuilder, period. FYI, our ParserPool impls do that by
default, since we're always dealing with namespaces.<br>
<br>
<br>
Setting that would get you past that error. However, then you're
going to get another error because your element QName isn't a
registered/known element type. I thought somewhere we had code that
would automatically return an XSAny for unknown element types, but
apparently not in these particular helper methods. So you have to
deal with it specifically.<br>
<br>
Since you know in advance that this is the case, you just ask for
that kind of unmarshaller a-priori. Combining that with use of our
global ParserPool, a variant of this will work:<br>
<br>
<br>
<tt>// The DBF via the global ParserPool here is already
namespace-aware.</tt><tt><br>
</tt><tt>Document doc =
XMLObjectProviderRegistrySupport.getParserPool().parse(new
StringReader(xmlString));</tt><tt><br>
</tt><tt> </tt><tt><br>
</tt><tt>// Get the unmarshaller specifically for the default
provider (XSAny)</tt><tt><br>
</tt><tt>Unmarshaller unmarshaller =
XMLObjectSupport.getUnmarshaller(</tt><tt><br>
</tt><tt>
XMLObjectProviderRegistrySupport.getDefaultProviderQName());</tt><tt><br>
</tt><tt> </tt><tt><br>
</tt><tt>// Now just unmarshall the root element. This will be an
instance of XSAny.</tt><tt><br>
</tt><tt>XMLObject xmlObject =
unmarshaller.unmarshall(doc.getDocumentElement());</tt><br>
<br>
<br>
3 lines of code, so not so bad...<br>
<br>
If you're just going to hand this to an XMLObjectAttributeValue,
then you're done. If you actually want to work with it, mutate it,
etc, you'd cast xmlObject to XSAny and use its API. <br>
<br>
As I mentioned, as an alternative to string building and parsing,
etc, you could just create an XSAny directly, and set its values.
This is a cleaner and more performant approach (the parsing above is
relatively expensive). Example:<br>
<br>
<br>
<tt>// The outer <attributes> element<br>
XSAny attributes = (XSAny) XMLObjectSupport.getBuilder(</tt><tt><br>
</tt><tt>
XMLObjectProviderRegistrySupport.getDefaultProviderQName())</tt><tt><br>
</tt><tt> .buildObject(new QName("foo", "attributes", "n"));</tt><tt><br>
</tt><tt> </tt><tt><br>
</tt><tt>// The inner <attribute> element<br>
XSAny attribute = (XSAny) XMLObjectSupport.getBuilder(</tt><tt><br>
</tt><tt>
XMLObjectProviderRegistrySupport.getDefaultProviderQName())</tt><tt><br>
</tt><tt> .buildObject(new QName("foo", "attribute", "n"));</tt><tt><br>
</tt><tt> </tt><tt><br>
</tt><tt>// Add attribs on the inner element<br>
attribute.getUnknownAttributes().put(new QName("foo", "name",
"n"), "AcctId");</tt><tt><br>
</tt><tt>attribute.getUnknownAttributes().put(new QName("foo",
"value", "n"), "000004D");</tt><tt><br>
</tt><tt> <br>
// Add the inner element as child of the outer element<br>
</tt><tt></tt><tt>attributes.getUnknownXMLObjects().add(attribute);</tt><tt><br>
</tt><br>
<br>
You can build up pretty much any XML structure that way as an
XMLObject, albeit a little inefficiently and verbosely.<br>
<br>
Finally, if you were gong to do this a lot, use in different places,
etc, it would make more sense to just implement custom XMLObject
provider for your XML type(s).<br>
<br>
<br>
--Brent<br>
<br>
<br>
<br>
</body>
</html>