Java Code Examples for org.w3c.dom.Element#getAttributeNodeNS()

The following examples show how to use org.w3c.dom.Element#getAttributeNodeNS() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: XmlCombiner.java    From xml-combiner with Apache License 2.0 6 votes vote down vote up
/**
 * Copies attributes from one {@link Element} to the other.
 * @param source source element
 * @param destination destination element
 */
private void copyAttributes(@Nullable Element source, Element destination) {
	if (source == null) {
		return;
	}
	NamedNodeMap attributes = source.getAttributes();
	for (int i = 0; i < attributes.getLength(); i++) {
		Attr attribute = (Attr) attributes.item(i);
		Attr destAttribute = destination.getAttributeNodeNS(attribute.getNamespaceURI(), attribute.getName());

		if (destAttribute == null) {
			destination.setAttributeNodeNS((Attr) document.importNode(attribute, true));
		} else {
			destAttribute.setValue(attribute.getValue());
		}
	}
}
 
Example 2
Source File: Documents.java    From ttt with BSD 2-Clause "Simplified" License 6 votes vote down vote up
public static void assignIdAttributes(Element elt, List<QName> idAttrs) {
    for (QName idAttr : idAttrs) {
        String ns = idAttr.getNamespaceURI();
        String ln = idAttr.getLocalPart();
        if (ns.length() == 0)
            ns = null;
        Attr a = elt.getAttributeNodeNS(ns, ln);
        if (a != null) {
            elt.setIdAttributeNode(a, true);
            break;
        }
    }
    for (Node n = elt.getFirstChild(); n != null; n = n.getNextSibling()) {
        if (n instanceof Element) {
            assignIdAttributes((Element) n, idAttrs);
        }
    }
}
 
Example 3
Source File: SignatureAlgorithm.java    From jdk8u-jdk with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Constructor SignatureAlgorithm
 *
 * @param element
 * @param baseURI
 * @param secureValidation
 * @throws XMLSecurityException
 */
public SignatureAlgorithm(
    Element element, String baseURI, boolean secureValidation
) throws XMLSecurityException {
    super(element, baseURI);
    algorithmURI = this.getURI();

    Attr attr = element.getAttributeNodeNS(null, "Id");
    if (attr != null) {
        element.setIdAttributeNode(attr, true);
    }

    if (secureValidation && (XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5.equals(algorithmURI)
        || XMLSignature.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5.equals(algorithmURI))) {
        Object exArgs[] = { algorithmURI };

        throw new XMLSecurityException("signature.signatureAlgorithm", exArgs);
    }

    signatureAlgorithm = getSignatureAlgorithmSpi(algorithmURI);
    signatureAlgorithm.engineGetContextFromElement(this.constructionElement);
}
 
Example 4
Source File: DOMSignatureProperties.java    From jdk8u-dev-jdk with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Creates a <code>DOMSignatureProperties</code> from an element.
 *
 * @param propsElem a SignatureProperties element
 * @throws MarshalException if a marshalling error occurs
 */
public DOMSignatureProperties(Element propsElem, XMLCryptoContext context)
    throws MarshalException
{
    // unmarshal attributes
    Attr attr = propsElem.getAttributeNodeNS(null, "Id");
    if (attr != null) {
        id = attr.getValue();
        propsElem.setIdAttributeNode(attr, true);
    } else {
        id = null;
    }

    NodeList nodes = propsElem.getChildNodes();
    int length = nodes.getLength();
    List<SignatureProperty> properties =
        new ArrayList<SignatureProperty>(length);
    for (int i = 0; i < length; i++) {
        Node child = nodes.item(i);
        if (child.getNodeType() == Node.ELEMENT_NODE) {
            String name = child.getLocalName();
            if (!name.equals("SignatureProperty")) {
                throw new MarshalException("Invalid element name: " + name +
                                           ", expected SignatureProperty");
            }
            properties.add(new DOMSignatureProperty((Element)child,
                                                    context));
        }
    }
    if (properties.isEmpty()) {
        throw new MarshalException("properties cannot be empty");
    } else {
        this.properties = Collections.unmodifiableList(properties);
    }
}
 
Example 5
Source File: DOMRetrievalMethod.java    From jdk8u-jdk with GNU General Public License v2.0 5 votes vote down vote up
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
    throws MarshalException
{
    Document ownerDoc = DOMUtils.getOwnerDocument(parent);
    Element rmElem = DOMUtils.createElement(ownerDoc, "RetrievalMethod",
                                            XMLSignature.XMLNS, dsPrefix);

    // add URI and Type attributes
    DOMUtils.setAttribute(rmElem, "URI", uri);
    DOMUtils.setAttribute(rmElem, "Type", type);

    // add Transforms elements
    if (!transforms.isEmpty()) {
        Element transformsElem = DOMUtils.createElement(ownerDoc,
                                                        "Transforms",
                                                        XMLSignature.XMLNS,
                                                        dsPrefix);
        rmElem.appendChild(transformsElem);
        for (Transform transform : transforms) {
            ((DOMTransform)transform).marshal(transformsElem,
                                               dsPrefix, context);
        }
    }

    parent.appendChild(rmElem);

    // save here node
    here = rmElem.getAttributeNodeNS(null, "URI");
}
 
Example 6
Source File: XMLUtils.java    From jdk8u_jdk with GNU General Public License v2.0 5 votes vote down vote up
/**
 * This method spreads all namespace attributes in a DOM document to their
 * children. This is needed because the XML Signature XPath transform
 * must evaluate the XPath against all nodes in the input, even against
 * XPath namespace nodes. Through a bug in XalanJ2, the namespace nodes are
 * not fully visible in the Xalan XPath model, so we have to do this by
 * hand in DOM spaces so that the nodes become visible in XPath space.
 *
 * @param doc
 * @see <A HREF="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2650">
 * Namespace axis resolution is not XPath compliant </A>
 */
public static void circumventBug2650(Document doc) {

    Element documentElement = doc.getDocumentElement();

    // if the document element has no xmlns definition, we add xmlns=""
    Attr xmlnsAttr =
        documentElement.getAttributeNodeNS(Constants.NamespaceSpecNS, "xmlns");

    if (xmlnsAttr == null) {
        documentElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns", "");
    }

    XMLUtils.circumventBug2650internal(doc);
}
 
Example 7
Source File: KeyInfo.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Constructor KeyInfo
 *
 * @param element
 * @param baseURI
 * @throws XMLSecurityException
 */
public KeyInfo(Element element, String baseURI) throws XMLSecurityException {
    super(element, baseURI);

    Attr attr = element.getAttributeNodeNS(null, "Id");
    if (attr != null) {
        element.setIdAttributeNode(attr, true);
    }
}
 
Example 8
Source File: DOMManifest.java    From jdk8u-dev-jdk with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Creates a <code>DOMManifest</code> from an element.
 *
 * @param manElem a Manifest element
 */
public DOMManifest(Element manElem, XMLCryptoContext context,
                   Provider provider)
    throws MarshalException
{
    Attr attr = manElem.getAttributeNodeNS(null, "Id");
    if (attr != null) {
        this.id = attr.getValue();
        manElem.setIdAttributeNode(attr, true);
    } else {
        this.id = null;
    }

    boolean secVal = Utils.secureValidation(context);

    Element refElem = DOMUtils.getFirstChildElement(manElem, "Reference");
    List<Reference> refs = new ArrayList<Reference>();
    refs.add(new DOMReference(refElem, context, provider));

    refElem = DOMUtils.getNextSiblingElement(refElem);
    while (refElem != null) {
        String localName = refElem.getLocalName();
        if (!localName.equals("Reference")) {
            throw new MarshalException("Invalid element name: " +
                                       localName + ", expected Reference");
        }
        refs.add(new DOMReference(refElem, context, provider));
        if (secVal && (refs.size() > DOMSignedInfo.MAXIMUM_REFERENCE_COUNT)) {
            String error = "A maxiumum of " + DOMSignedInfo.MAXIMUM_REFERENCE_COUNT + " "
                + "references per Manifest are allowed with secure validation";
            throw new MarshalException(error);
        }
        refElem = DOMUtils.getNextSiblingElement(refElem);
    }
    this.references = Collections.unmodifiableList(refs);
}
 
Example 9
Source File: DOMManifest.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Creates a <code>DOMManifest</code> from an element.
 *
 * @param manElem a Manifest element
 */
public DOMManifest(Element manElem, XMLCryptoContext context,
                   Provider provider)
    throws MarshalException
{
    Attr attr = manElem.getAttributeNodeNS(null, "Id");
    if (attr != null) {
        this.id = attr.getValue();
        manElem.setIdAttributeNode(attr, true);
    } else {
        this.id = null;
    }

    boolean secVal = Utils.secureValidation(context);

    Element refElem = DOMUtils.getFirstChildElement(manElem, "Reference");
    List<Reference> refs = new ArrayList<Reference>();
    refs.add(new DOMReference(refElem, context, provider));

    refElem = DOMUtils.getNextSiblingElement(refElem);
    while (refElem != null) {
        String localName = refElem.getLocalName();
        if (!localName.equals("Reference")) {
            throw new MarshalException("Invalid element name: " +
                                       localName + ", expected Reference");
        }
        refs.add(new DOMReference(refElem, context, provider));
        if (secVal && (refs.size() > DOMSignedInfo.MAXIMUM_REFERENCE_COUNT)) {
            String error = "A maxiumum of " + DOMSignedInfo.MAXIMUM_REFERENCE_COUNT + " "
                + "references per Manifest are allowed with secure validation";
            throw new MarshalException(error);
        }
        refElem = DOMUtils.getNextSiblingElement(refElem);
    }
    this.references = Collections.unmodifiableList(refs);
}
 
Example 10
Source File: DOMUtils.java    From cxf-fediz with Apache License 2.0 5 votes vote down vote up
public static String getAttribute(Element element, QName attName) {
    Attr attr;
    if (StringUtils.isEmpty(attName.getNamespaceURI())) {
        attr = element.getAttributeNode(attName.getLocalPart());
    } else {
        attr = element.getAttributeNodeNS(attName.getNamespaceURI(), attName.getLocalPart());
    }
    return attr == null ? null : attr.getValue();
}
 
Example 11
Source File: XmlUtil.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
public static String getAttributeNSOrNull(
    Element e,
    String name,
    String nsURI) {
    Attr a = e.getAttributeNodeNS(nsURI, name);
    if (a == null)
        return null;
    return a.getValue();
}
 
Example 12
Source File: DOMKeyInfo.java    From openjdk-jdk8u with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Creates a <code>DOMKeyInfo</code> from XML.
 *
 * @param kiElem KeyInfo element
 */
public DOMKeyInfo(Element kiElem, XMLCryptoContext context,
                  Provider provider)
    throws MarshalException
{
    // get Id attribute, if specified
    Attr attr = kiElem.getAttributeNodeNS(null, "Id");
    if (attr != null) {
        id = attr.getValue();
        kiElem.setIdAttributeNode(attr, true);
    } else {
        id = null;
    }

    // get all children nodes
    NodeList nl = kiElem.getChildNodes();
    int length = nl.getLength();
    if (length < 1) {
        throw new MarshalException
            ("KeyInfo must contain at least one type");
    }
    List<XMLStructure> content = new ArrayList<XMLStructure>(length);
    for (int i = 0; i < length; i++) {
        Node child = nl.item(i);
        // ignore all non-Element nodes
        if (child.getNodeType() != Node.ELEMENT_NODE) {
            continue;
        }
        Element childElem = (Element)child;
        String localName = childElem.getLocalName();
        if (localName.equals("X509Data")) {
            content.add(new DOMX509Data(childElem));
        } else if (localName.equals("KeyName")) {
            content.add(new DOMKeyName(childElem));
        } else if (localName.equals("KeyValue")) {
            content.add(DOMKeyValue.unmarshal(childElem));
        } else if (localName.equals("RetrievalMethod")) {
            content.add(new DOMRetrievalMethod(childElem,
                                               context, provider));
        } else if (localName.equals("PGPData")) {
            content.add(new DOMPGPData(childElem));
        } else { //may be MgmtData, SPKIData or element from other namespace
            content.add(new javax.xml.crypto.dom.DOMStructure((childElem)));
        }
    }
    keyInfoTypes = Collections.unmodifiableList(content);
}
 
Example 13
Source File: DOMUtil.java    From TencentKona-8 with GNU General Public License v2.0 4 votes vote down vote up
public static Attr getAttrNS(Element elem, String nsUri,
        String localName) {
    return elem.getAttributeNodeNS(nsUri, localName);
}
 
Example 14
Source File: DOMRetrievalMethod.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Creates a <code>DOMRetrievalMethod</code> from an element.
 *
 * @param rmElem a RetrievalMethod element
 */
public DOMRetrievalMethod(Element rmElem, XMLCryptoContext context,
                          Provider provider)
    throws MarshalException
{
    // get URI and Type attributes
    uri = DOMUtils.getAttributeValue(rmElem, "URI");
    type = DOMUtils.getAttributeValue(rmElem, "Type");

    // get here node
    here = rmElem.getAttributeNodeNS(null, "URI");

    boolean secVal = Utils.secureValidation(context);

    // get Transforms, if specified
    List<Transform> transforms = new ArrayList<Transform>();
    Element transformsElem = DOMUtils.getFirstChildElement(rmElem);

    if (transformsElem != null) {
        String localName = transformsElem.getLocalName();
        if (!localName.equals("Transforms")) {
            throw new MarshalException("Invalid element name: " +
                                       localName + ", expected Transforms");
        }
        Element transformElem =
            DOMUtils.getFirstChildElement(transformsElem, "Transform");
        transforms.add(new DOMTransform(transformElem, context, provider));
        transformElem = DOMUtils.getNextSiblingElement(transformElem);
        while (transformElem != null) {
            String name = transformElem.getLocalName();
            if (!name.equals("Transform")) {
                throw new MarshalException("Invalid element name: " +
                                           name + ", expected Transform");
            }
            transforms.add
                (new DOMTransform(transformElem, context, provider));
            if (secVal && (transforms.size() > DOMReference.MAXIMUM_TRANSFORM_COUNT)) {
                String error = "A maxiumum of " + DOMReference.MAXIMUM_TRANSFORM_COUNT + " "
                    + "transforms per Reference are allowed with secure validation";
                throw new MarshalException(error);
            }
            transformElem = DOMUtils.getNextSiblingElement(transformElem);
        }
    }
    if (transforms.isEmpty()) {
        this.transforms = Collections.emptyList();
    } else {
        this.transforms = Collections.unmodifiableList(transforms);
    }
}
 
Example 15
Source File: DOMRetrievalMethod.java    From openjdk-jdk8u with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Creates a <code>DOMRetrievalMethod</code> from an element.
 *
 * @param rmElem a RetrievalMethod element
 */
public DOMRetrievalMethod(Element rmElem, XMLCryptoContext context,
                          Provider provider)
    throws MarshalException
{
    // get URI and Type attributes
    uri = DOMUtils.getAttributeValue(rmElem, "URI");
    type = DOMUtils.getAttributeValue(rmElem, "Type");

    // get here node
    here = rmElem.getAttributeNodeNS(null, "URI");

    boolean secVal = Utils.secureValidation(context);

    // get Transforms, if specified
    List<Transform> transforms = new ArrayList<Transform>();
    Element transformsElem = DOMUtils.getFirstChildElement(rmElem);

    if (transformsElem != null) {
        String localName = transformsElem.getLocalName();
        if (!localName.equals("Transforms")) {
            throw new MarshalException("Invalid element name: " +
                                       localName + ", expected Transforms");
        }
        Element transformElem =
            DOMUtils.getFirstChildElement(transformsElem, "Transform");
        transforms.add(new DOMTransform(transformElem, context, provider));
        transformElem = DOMUtils.getNextSiblingElement(transformElem);
        while (transformElem != null) {
            String name = transformElem.getLocalName();
            if (!name.equals("Transform")) {
                throw new MarshalException("Invalid element name: " +
                                           name + ", expected Transform");
            }
            transforms.add
                (new DOMTransform(transformElem, context, provider));
            if (secVal && Policy.restrictNumTransforms(transforms.size())) {
                String error = "A maximum of " + Policy.maxTransforms()
                    + " transforms per Reference are allowed when"
                    + " secure validation is enabled";
                throw new MarshalException(error);
            }
            transformElem = DOMUtils.getNextSiblingElement(transformElem);
        }
    }
    if (transforms.isEmpty()) {
        this.transforms = Collections.emptyList();
    } else {
        this.transforms = Collections.unmodifiableList(transforms);
    }
}
 
Example 16
Source File: DOMKeyInfo.java    From jdk8u_jdk with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Creates a <code>DOMKeyInfo</code> from XML.
 *
 * @param kiElem KeyInfo element
 */
public DOMKeyInfo(Element kiElem, XMLCryptoContext context,
                  Provider provider)
    throws MarshalException
{
    // get Id attribute, if specified
    Attr attr = kiElem.getAttributeNodeNS(null, "Id");
    if (attr != null) {
        id = attr.getValue();
        kiElem.setIdAttributeNode(attr, true);
    } else {
        id = null;
    }

    // get all children nodes
    NodeList nl = kiElem.getChildNodes();
    int length = nl.getLength();
    if (length < 1) {
        throw new MarshalException
            ("KeyInfo must contain at least one type");
    }
    List<XMLStructure> content = new ArrayList<XMLStructure>(length);
    for (int i = 0; i < length; i++) {
        Node child = nl.item(i);
        // ignore all non-Element nodes
        if (child.getNodeType() != Node.ELEMENT_NODE) {
            continue;
        }
        Element childElem = (Element)child;
        String localName = childElem.getLocalName();
        if (localName.equals("X509Data")) {
            content.add(new DOMX509Data(childElem));
        } else if (localName.equals("KeyName")) {
            content.add(new DOMKeyName(childElem));
        } else if (localName.equals("KeyValue")) {
            content.add(DOMKeyValue.unmarshal(childElem));
        } else if (localName.equals("RetrievalMethod")) {
            content.add(new DOMRetrievalMethod(childElem,
                                               context, provider));
        } else if (localName.equals("PGPData")) {
            content.add(new DOMPGPData(childElem));
        } else { //may be MgmtData, SPKIData or element from other namespace
            content.add(new javax.xml.crypto.dom.DOMStructure((childElem)));
        }
    }
    keyInfoTypes = Collections.unmodifiableList(content);
}
 
Example 17
Source File: DOMReference.java    From jdk8u_jdk with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Creates a <code>DOMReference</code> from an element.
 *
 * @param refElem a Reference element
 */
public DOMReference(Element refElem, XMLCryptoContext context,
                    Provider provider)
    throws MarshalException
{
    boolean secVal = Utils.secureValidation(context);

    // unmarshal Transforms, if specified
    Element nextSibling = DOMUtils.getFirstChildElement(refElem);
    List<Transform> transforms = new ArrayList<Transform>(5);
    if (nextSibling.getLocalName().equals("Transforms")) {
        Element transformElem = DOMUtils.getFirstChildElement(nextSibling,
                                                              "Transform");
        transforms.add(new DOMTransform(transformElem, context, provider));
        transformElem = DOMUtils.getNextSiblingElement(transformElem);
        while (transformElem != null) {
            String localName = transformElem.getLocalName();
            if (!localName.equals("Transform")) {
                throw new MarshalException(
                    "Invalid element name: " + localName +
                    ", expected Transform");
            }
            transforms.add
                (new DOMTransform(transformElem, context, provider));
            if (secVal && Policy.restrictNumTransforms(transforms.size())) {
                String error = "A maximum of " + Policy.maxTransforms()
                    + " transforms per Reference are allowed when"
                    + " secure validation is enabled";
                throw new MarshalException(error);
            }
            transformElem = DOMUtils.getNextSiblingElement(transformElem);
        }
        nextSibling = DOMUtils.getNextSiblingElement(nextSibling);
    }
    if (!nextSibling.getLocalName().equals("DigestMethod")) {
        throw new MarshalException("Invalid element name: " +
                                   nextSibling.getLocalName() +
                                   ", expected DigestMethod");
    }

    // unmarshal DigestMethod
    Element dmElem = nextSibling;
    this.digestMethod = DOMDigestMethod.unmarshal(dmElem);
    String digestMethodAlgorithm = this.digestMethod.getAlgorithm();
    if (secVal && Policy.restrictAlg(digestMethodAlgorithm)) {
        throw new MarshalException(
            "It is forbidden to use algorithm " + digestMethodAlgorithm +
            " when secure validation is enabled"
        );
    }

    // unmarshal DigestValue
    Element dvElem = DOMUtils.getNextSiblingElement(dmElem, "DigestValue");
    try {
        this.digestValue = Base64.decode(dvElem);
    } catch (Base64DecodingException bde) {
        throw new MarshalException(bde);
    }

    // check for extra elements
    if (DOMUtils.getNextSiblingElement(dvElem) != null) {
        throw new MarshalException(
            "Unexpected element after DigestValue element");
    }

    // unmarshal attributes
    this.uri = DOMUtils.getAttributeValue(refElem, "URI");

    Attr attr = refElem.getAttributeNodeNS(null, "Id");
    if (attr != null) {
        this.id = attr.getValue();
        refElem.setIdAttributeNode(attr, true);
    } else {
        this.id = null;
    }

    this.type = DOMUtils.getAttributeValue(refElem, "Type");
    this.here = refElem.getAttributeNodeNS(null, "URI");
    this.refElem = refElem;
    this.transforms = transforms;
    this.allTransforms = transforms;
    this.appliedTransformData = null;
    this.provider = provider;
}
 
Example 18
Source File: XMLUtils.java    From openjdk-jdk8u with GNU General Public License v2.0 2 votes vote down vote up
/**
 * Returns the attribute value for the attribute with the specified name.
 * Returns null if there is no such attribute, or
 * the empty string if the attribute value is empty.
 *
 * <p>This works around a limitation of the DOM
 * <code>Element.getAttributeNode</code> method, which does not distinguish
 * between an unspecified attribute and an attribute with a value of
 * "" (it returns "" for both cases).
 *
 * @param elem the element containing the attribute
 * @param name the name of the attribute
 * @return the attribute value (may be null if unspecified)
 */
public static String getAttributeValue(Element elem, String name) {
    Attr attr = elem.getAttributeNodeNS(null, name);
    return (attr == null) ? null : attr.getValue();
}
 
Example 19
Source File: DOMUtils.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 2 votes vote down vote up
/**
 * Returns the attribute value for the attribute with the specified name.
 * Returns null if there is no such attribute, or
 * the empty string if the attribute value is empty.
 *
 * <p>This works around a limitation of the DOM
 * <code>Element.getAttributeNode</code> method, which does not distinguish
 * between an unspecified attribute and an attribute with a value of
 * "" (it returns "" for both cases).
 *
 * @param elem the element containing the attribute
 * @param name the name of the attribute
 * @return the attribute value (may be null if unspecified)
 */
public static String getAttributeValue(Element elem, String name) {
    Attr attr = elem.getAttributeNodeNS(null, name);
    return (attr == null) ? null : attr.getValue();
}
 
Example 20
Source File: XMLUtils.java    From openjdk-8-source with GNU General Public License v2.0 2 votes vote down vote up
/**
 * Returns the attribute value for the attribute with the specified name.
 * Returns null if there is no such attribute, or
 * the empty string if the attribute value is empty.
 *
 * <p>This works around a limitation of the DOM
 * <code>Element.getAttributeNode</code> method, which does not distinguish
 * between an unspecified attribute and an attribute with a value of
 * "" (it returns "" for both cases).
 *
 * @param elem the element containing the attribute
 * @param name the name of the attribute
 * @return the attribute value (may be null if unspecified)
 */
public static String getAttributeValue(Element elem, String name) {
    Attr attr = elem.getAttributeNodeNS(null, name);
    return (attr == null) ? null : attr.getValue();
}