
	import java.io.IOException;

	import org.xml.sax.Attributes;
	import org.xml.sax.ContentHandler;
	import org.xml.sax.Locator;
	import org.xml.sax.SAXException;
	import org.xml.sax.XMLReader;

import org.apache.xerces.parsers.SAXParser;

	/**
     * XMLSAX przyjmuje ścieżkę dostępu do pliku XML, który parsuje
     * za pomocą parsera DOM i wyświetla sparsowaną zawartość.   
     * 
	 * @author Wiesław Dudek
	 * @version 1.0
	 */
	
	public class XMLSAX {

	    /**
	     * Wykonywane jest parsowanie pliku i wyświetlanie zawartości.
	     * 
	     * @param xml String ścieżka dostępu do pliku XML.
	     */
	    public void parseIt(String xml) {
	        System.out.println("Parsowanie pliku XML: " + xml + "\n\n");	    	
	        
	        // tworzymy procedury obsługi komunikatów parsera
	        ContentHandler myHandler = new MyContentHandler();
	        
	        try {
	            // ładujemy parser
	            XMLReader parser = new SAXParser();
	                
	            // Zarejestruj procedurę obsługi zawartości.
	            parser.setContentHandler(myHandler);
	            
	            // parsujemy dokument
	            parser.parse(xml);
	            
	        } catch (IOException ex) {
	            System.out.println("Błąd podczas odczytywania pliku XML: " + ex.getMessage());
	        } catch (SAXException ex) {
	            System.out.println("Błąd podczas parsowania: " + ex.getMessage());
	        }
	            
	    }
	    
	    /**
	     * wejście programu
	     */
	    public static void main(String[] args) {
	        if (args.length != 1) {
	            System.out.println("Użycie: java XMLSAX <ścieżka do pliku XML>");
	            System.exit(0);
	        }
	        
	        String xml = args[0];
	    
	        XMLSAX parserDemo = new XMLSAX();
	        parserDemo.parseIt(xml);
	    }
	}

	/**
	 * MyContentHandler implementuje interfejs SAX 
	 * ContentHandler i określa sposób obsługi komunikatów parsera.
	 */
	class MyContentHandler implements ContentHandler {

	    /** 
	     * aktualna pozycja parsera  
	     */
	    private Locator pos;
	    
	    /**
	     * Ustawienie obiektu Locator do późniejszego wykorzystania 
	     *
	     * @param pos Locator obiekt umożliwiający uzyskanie informacji
	     * o miejscu parsowania
	     */
	    public void setDocumentLocator(Locator pos) {
	        System.out.println("ustawiono Locator");
	        this.pos = pos;	    	
	    }
	    
	    /**
	     * Wywoływana przed rozpoczęciem parsowania
	     *  
	     * @throws SAXException 
	     */
	    public void startDocument() throws SAXException {
	        System.out.println("Rozpoczęcie parsowania");	    	
	    }

	    /**
	     * Wywołana po zakończeniu parsowania
	     * 
	     * @throws SAXException
	     */    
	    public void endDocument() throws SAXException {
	        System.out.println("Zakończenie parsowania");	    	
	    }
	    
	    /**
	     * Natrafiono na instrukcję przetwarzania typu <?...
	     *
	     * @param object String obiekt docelowy instrukcji przetwarzania
	     * @param data <code>String</code> dane 
	     * @throws SAXException
	     */         
	    public void processingInstruction(String object, String data)
	        throws SAXException {
	        System.out.println("Instrukcja przetwarzania: Obiekt=" + object + "; Dane=" + data);	    	
	    }
	    
	    /**
	     *  Początek odwzorowania przestrzeni nazw. 
	     *  Pojawia się przed odwołniem do samego elementu.
	     *
	     * @param prefix String przedrostek przestrzeni nazw
	     * @param namespace String prestrzeń nazw
	     * @throws SAXException
	     */                  
	    public void startPrefixMapping(String prefix, String namespace) {
	        System.out.println("Początek odwzorowania dla przedrostka " + prefix + 
                    " odwzorowanego dla URI " +namespace);
	    	
	    }

	    /**
	     *  Koniec odwzorowania przedrostka
	     *
	     * @param prefix String przedrostek przestrzeni nazw
	     * @throws SAXException
	     */      
	    public void endPrefixMapping(String prefix) {
	        System.out.println("Koniec odwzorowania dla przedrostka " + prefix);
	    }
	    
	    /**
	     * Początek przetwarzania właściwego elementu. Przekazywane są atrybuty
	     * elementu poza: 
	     * xmlns:[prefix]
	     * xsi:schemaLocation
	     *
	     * @param namespace String przestrzeń nazw o ile istnieje
	     * @param name String nazwa elementu bez prefiksu przestrzeni nazw
	     * @param prefixName String [prefix]:[name].
	     * @param attribs Attributes atrybuty elementu
	     * @throws SAXException
	     */     
	    public void startElement(String namespace, String name,
	                             String prefixName, Attributes attribs)
	        throws SAXException {
	        System.out.print("początek elementu: " + name);
	        if (!namespace.equals("")) {
	            System.out.println(" w przestrzeni nazw " + namespace + 
	                               " (" + prefixName + ")");
	        } else {
	            System.out.println(" nie posiada skojarzonej przestrzeni nazw");
	        }

	        for (int i=0; i<attribs.getLength(); i++)
	            System.out.println("  Atrybut: " + attribs.getLocalName(i) +
	                               "=" + attribs.getValue(i));          
	    	
	    }
	    
	    /** 
	     * Parser dotarł do końca elementu
	     * 
	     * @param namespace String przestrzeń nazw o ile istnieje
	     * @param name String nazwa elementu bez prefiksu przestrzeni nazw
	     * @param prefixName String [prefix]:[name]
	     * 
	     * @throws SAXException
	     */        
	    public void endElement(String namespace, String name, 
	                           String prefixName) 
	        throws SAXException {
	        System.out.println("koniec elementu: " + name + "\n");	    	
	    }
	    /**
	     * Dane tekstowe wewnątrz elementu
	     *
	     * @param chars char[] znaki wewnątrz elementu
	     * @param begin int indeks początku danych w tablicy chars
	     * @param end int indeks końca danych w tablicy chars
	     * @throws SAXException
	     */         
	    public void characters(char[] chars, int begin, int end) 
	        throws SAXException {
	    	
	        String str = new String(chars, begin, end);
	        System.out.println("tekst: " + str);

	    }

	    /**
	     * Parser informuje o znalezionych i zignorowanych białych znakach 
	     * 
	     * @param chars char[] znaki wewnątrz elementu
	     * @param begin int indeks początku danych w tablicy chars
	     * @param end int indeks końca danych w tablicy chars
	     * @throws SAXException
	     */
	    public void ignorableWhitespace(char[] chars, int begin, int end)
	        throws SAXException {
	    	
	        String str = new String(chars, begin, end);
	        System.out.println("zignorowane znaki: [" + str + "]");

	    }

	    /**
	     * Informacja o pominiętej przez parser encji 
	     *
	     * @param name String nazwa encji
	     * @throws SAXException
	     */
	    public void skippedEntity(String name) throws SAXException {
	        System.out.println("Pominięta encja: " + name);
	    }

	}
