
/*
This Java source file was generated by test-to-java.xsl
and is a derived work from the source document.
The source document contained the following notice:


Copyright (c) 2001 World Wide Web Consortium, 
(Massachusetts Institute of Technology, Institut National de
Recherche en Informatique et en Automatique, Keio University).  All 
Rights Reserved.  This program is distributed under the W3C's Software
Intellectual Property License.  This program is distributed in the 
hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE.  

See W3C License http://www.w3.org/Consortium/Legal/ for more details.

*/

package org.w3c.domts.level2.core;

import org.w3c.dom.*;


import org.w3c.domts.DOMTestCase;
import org.w3c.domts.DOMTestDocumentBuilderFactory;



/**
 *       The method getAttributeNodeNS retrieves an Attr node by local name and namespace URI.
 *       Create a new element node and add 2 new attribute nodes to it that have the same 
 *       local name but different namespaceURIs and prefixes.  
 *       Retrieve an attribute using namespace and localname and check its value, name and 
 *       namespaceURI.
 *     
* @author IBM
* @author Neil Delima
* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElGetAtNodeNS">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-ElGetAtNodeNS</a>
*/
public final class elementgetattributenodens01 extends DOMTestCase {

   /**
    * Constructor.
    * @param factory document factory, may not be null
    * @throws org.w3c.domts.DOMTestIncompatibleException Thrown if test is not compatible with parser configuration
    */
   public elementgetattributenodens01(final DOMTestDocumentBuilderFactory factory)  throws org.w3c.domts.DOMTestIncompatibleException {

      org.w3c.domts.DocumentBuilderSetting[] settings = 
          new org.w3c.domts.DocumentBuilderSetting[] {
org.w3c.domts.DocumentBuilderSetting.namespaceAware
        };
        DOMTestDocumentBuilderFactory testFactory = factory.newInstance(settings);
        setFactory(testFactory);

    //
    //   check if loaded documents are supported for content type
    //
    String contentType = getContentType();
    preload(contentType, "staffNS", false);
    }

   /**
    * Runs the test case.
    * @throws Throwable Any uncaught exception causes test to fail
    */
   public void runTest() throws Throwable {
      Document doc;
      Element element;
      Attr attribute1;
      Attr attribute2;
      Attr newAttribute1;
      Attr newAttribute2;
      Attr attribute;
      String attrValue;
      String attrName;
      String attNodeName;
      String attrLocalName;
      String attrNS;
      doc = (Document) load("staffNS", false);
      element = doc.createElementNS("namespaceURI", "root");
      attribute1 = doc.createAttributeNS("http://www.w3.org/DOM/Level2", "l2:att");
      newAttribute1 = element.setAttributeNodeNS(attribute1);
      attribute2 = doc.createAttributeNS("http://www.w3.org/DOM/Level1", "att");
      newAttribute2 = element.setAttributeNodeNS(attribute2);
      attribute = element.getAttributeNodeNS("http://www.w3.org/DOM/Level2", "att");
      attrValue = attribute.getNodeValue();
      attrName = attribute.getName();
      attNodeName = attribute.getNodeName();
      attrLocalName = attribute.getLocalName();
      attrNS = attribute.getNamespaceURI();
      assertEquals("elementgetattributenodens01_attrValue", "", attrValue);
      assertEquals("elementgetattributenodens01_attrName", "l2:att", attrName);
      assertEquals("elementgetattributenodens01_attrNodeName", "l2:att", attNodeName);
      assertEquals("elementgetattributenodens01_attrLocalName", "att", attrLocalName);
      assertEquals("elementgetattributenodens01_attrNs", "http://www.w3.org/DOM/Level2", attrNS);
      }
   /**
    *  Gets URI that identifies the test.
    *  @return uri identifier of test
    */
   public String getTargetURI() {
      return "http://www.w3.org/2001/DOM-Test-Suite/level2/core/elementgetattributenodens01";
   }
   /**
    * Runs this test from the command line.
    * @param args command line arguments
    */
   public static void main(final String[] args) {
        DOMTestCase.doMain(elementgetattributenodens01.class, args);
   }
}

