
/*
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 "getElementsByTagNameNS(namespaceURI,localName)" method returns a NodeList
 *    of all descendant Elements with a given local name and namespace URI in the
 *    order in which they are encountered in a preorder traversal of this Element tree.
 *    
 *    Create a NodeList of all the descendant elements of the document element
 *    using the "http://www.nist.gov" as the namespaceURI and the special value "*" as the 
 *    localName.
 *    The method should return a NodeList of elements that have "http://www.nist.gov
 *    as a namespace URI.
 *    Derived from getElementsByTagNameNS03
* @author Curt Arnold
* @author Curt Arnold
* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#ID-1938918D">http://www.w3.org/TR/DOM-Level-2-Core/core#ID-1938918D</a>
*/
public final class getElementsByTagNameNS10 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 getElementsByTagNameNS10(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 docElem;
      NodeList elementList;
      Node child;
      String childName;
      java.util.List result = new java.util.ArrayList();
      
      java.util.List expectedResult = new java.util.ArrayList();
      expectedResult.add("employee");
      expectedResult.add("employeeId");
      expectedResult.add("name");
      expectedResult.add("position");
      expectedResult.add("salary");
      expectedResult.add("gender");
      expectedResult.add("address");
      expectedResult.add("emp:employee");
      expectedResult.add("emp:employeeId");
      expectedResult.add("emp:position");
      expectedResult.add("emp:salary");
      expectedResult.add("emp:gender");
      expectedResult.add("emp:address");
      expectedResult.add("address");
      
      doc = (Document) load("staffNS", false);
      docElem = doc.getDocumentElement();
      elementList = docElem.getElementsByTagNameNS("http://www.nist.gov", "*");
      for (int indexN1007E = 0; indexN1007E < elementList.getLength(); indexN1007E++) {
          child = (Node) elementList.item(indexN1007E);
    childName = child.getNodeName();
      result.add(childName);
        }
      assertEquals("nodeNames", expectedResult, result);
      }
   /**
    *  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/getElementsByTagNameNS10";
   }
   /**
    * Runs this test from the command line.
    * @param args command line arguments
    */
   public static void main(final String[] args) {
        DOMTestCase.doMain(getElementsByTagNameNS10.class, args);
   }
}

