Node valueNode = null; // ! Can come from rdf:value or rdf:resource.
if (xmlNode.hasChildNodes())
{
throw new XMPException(
"Nested content not allowed with rdf:resource or property attributes",
BADRDF);
}
// First figure out what XMP this maps to and remember the XML node for a simple value.
for (int i = 0; i < xmlNode.getAttributes().getLength(); i++)
{
Node attribute = xmlNode.getAttributes().item(i);
if ("xmlns".equals(attribute.getPrefix()) ||
(attribute.getPrefix() == null && "xmlns".equals(attribute.getNodeName())))
{
continue;
}
int attrTerm = getRDFTermKind (attribute);
switch (attrTerm)
{
case RDFTERM_ID :
// Nothing to do.
break;
case RDFTERM_RESOURCE :
if (hasNodeIDAttr)
{
throw new XMPException(
"Empty property element can't have both rdf:resource and rdf:nodeID",
BADRDF);
}
else if (hasValueAttr)
{
throw new XMPException(
"Empty property element can't have both rdf:value and rdf:resource",
BADXMP);
}
hasResourceAttr = true;
if (!hasValueAttr)
{
valueNode = attribute;
}
break;
case RDFTERM_NODE_ID:
if (hasResourceAttr)
{
throw new XMPException(
"Empty property element can't have both rdf:resource and rdf:nodeID",
BADRDF);
}
hasNodeIDAttr = true;
break;
case RDFTERM_OTHER:
if ("value".equals(attribute.getLocalName())
&& NS_RDF.equals(attribute.getNamespaceURI()))
{
if (hasResourceAttr)
{
throw new XMPException(
"Empty property element can't have both rdf:value and rdf:resource",
BADXMP);
}
hasValueAttr = true;
valueNode = attribute;
}
else if (!XML_LANG.equals(attribute.getNodeName()))
{
hasPropertyAttrs = true;
}
break;
default:
throw new XMPException("Unrecognized attribute of empty property element",
BADRDF);
}
}
// Create the right kind of child node and visit the attributes again
// to add the fields or qualifiers.
// ! Because of implementation vagaries,
// the xmpParent is the tree root for top level properties.
// ! The schema is found, created if necessary, by addChildNode.
XMPNode childNode = addChildNode(xmp, xmpParent, xmlNode, "", isTopLevel);
boolean childIsStruct = false;
if (hasValueAttr || hasResourceAttr)
{
childNode.setValue(valueNode != null ? valueNode.getNodeValue() : "");
if (!hasValueAttr)
{
// ! Might have both rdf:value and rdf:resource.
childNode.getOptions().setURI(true);
}
}
else if (hasPropertyAttrs)
{
childNode.getOptions().setStruct(true);
childIsStruct = true;
}
for (int i = 0; i < xmlNode.getAttributes().getLength(); i++)
{
Node attribute = xmlNode.getAttributes().item(i);
if (attribute == valueNode ||
"xmlns".equals(attribute.getPrefix()) ||
(attribute.getPrefix() == null && "xmlns".equals(attribute.getNodeName())))
{
continue; // Skip the rdf:value or rdf:resource attribute holding the value.
}
int attrTerm = getRDFTermKind (attribute);
switch (attrTerm)
{
case RDFTERM_ID :
case RDFTERM_NODE_ID :
break; // Ignore all rdf:ID and rdf:nodeID attributes.
case RDFTERM_RESOURCE :
addQualifierNode(childNode, "rdf:resource", attribute.getNodeValue());
break;
case RDFTERM_OTHER :
if (!childIsStruct)
{
addQualifierNode(
childNode, attribute.getNodeName(), attribute.getNodeValue());
}
else if (XML_LANG.equals(attribute.getNodeName()))
{
addQualifierNode (childNode, XML_LANG, attribute.getNodeValue());
}
else
{
addChildNode (xmp, childNode, attribute, attribute.getNodeValue(), false);
}
break;
default :
throw new XMPException("Unrecognized attribute of empty property element",
BADRDF);
}
}
}