# Exception bei getElementText



## kayf (21. Mrz 2011)

Hallo Forummitglieder,

ich habe zu meinem Problem folgenden Beitrag gefunden: http://www.java-forum.org/xml-co/35603-stax-problem.html , jedoch liegt bei mir das Problem scheinbar woanders, da es bei einem Element funktionert und bei dem anderen nicht.

Ich bin gerade dabei eine Software zu schreiben, bei der man aus einer XML eine GUI bauen kann.
Es funktioniert auch alles soweit, nur habe ich ein Problem, beim befüllen eines Textfeldes.
Ich benutze zu befüllen des Textfeldes parse.getElementText() innerhalb des XMLStreamConstants.START_ELEMENT. am besten Zeige ich euch mal einen Ausschnitt aus dem Code:


```
while ( parser.hasNext() ) 
		{ 
		  //System.out.println( "Event: " + parser.getEventType() ); 
		 
		  switch ( parser.getEventType() ) 
		  { 
		    case XMLStreamConstants.START_DOCUMENT: 
		      System.out.println( "START_DOKUMENT: " + parser.getVersion() ); 
		      break; 
		 
		    case XMLStreamConstants.END_DOCUMENT: 
		      System.out.println( "ENDE_DOKUMENT: " ); 
		      parser.close(); 
		      break; 
		 
		    case XMLStreamConstants.START_ELEMENT: 
		      spacer.append( "  " ); 
		      String elementName = parser.getLocalName();
		      System.out.println( spacer + "START_ELEMENT: " + elementName );
		      
		      if (elementName.equals("protokoll_style")){
		    	  for ( int i = 0; i < parser.getAttributeCount(); i++ ) {
		    		  String attributName = parser.getAttributeLocalName( i );
		    		  String attributWert = parser.getAttributeValue( i );
		    		  
		    		  if (attributName.equals("version")){
		    		  System.out.println( spacer + "  Version: "+attributWert); 
	                            //+ parser.getAttributeLocalName( i ) 
	                            //+ " Wert: " + parser.getAttributeValue( i ) );
		    		  }
		    		  if (attributName.equals("datum")){
			    		  System.out.println( spacer + "  Version vom: "+attributWert); 
			          }
		    	  }      
		      }
		      
		      else if (elementName.equals("attribut")){
		    	  String print ="";
		    	  for ( int i = 0; i < parser.getAttributeCount(); i++ ) {
		    		  String attributName = parser.getAttributeLocalName(i);
		    		  String attributWert = parser.getAttributeValue(i);
		    		  
		    		  if (attributName.equals("typ")){
		    			  if (attributWert.equals("textfeld")){
		    				  print += "Textfeld mit Namen: ";
		    				  al_typ.add("textfeld");
		    				  //al_name.add(parser.getAttributeValue(i+1));
		    				  al_jPanel.add(null);
		    				  al_jTextArea.add(null);
		    				  al_jCheckBox.add(null);
		    				  al_jRadioButton.add(null);
		    				  al_jText.add(new JTextField());
		    				//Text bestimmen falls vorhanden
		    				  	if (parser.isStartElement()){
		    				  		String text = parser.getElementText();
		    				  		if (!text.equals("")){
		    				  			al_jText.get(al_jText.size()-1).setText(text); //GEHT NICHT
		    				  		}
		    				  	}
		    			  }
		    			  
		    			  else if (attributWert.equals("label")){
		    				  al_typ.add("label");
		    				  //al_name.add(parser.getAttributeValue(i+1));
		    				  al_jPanel.add(null);
		    				  al_jText.add(null);
		    				  al_jCheckBox.add(null);
		    				  al_jRadioButton.add(null);
		    				  al_jTextArea.add(null);
		    			  }

		    		  else if (attributName.equals("name")){
		    			  print += attributWert;
		    			  al_name.add(parser.getAttributeValue(i));
		    		  }
		    		  
		    	  }	  
		    	  System.out.println( spacer + print);
		      }
		      else if (elementName.equals("yesno")){
		    	  /*Hier ist zu beachten, dass immer gleich zwei felder gefüllt
		    	   * werden müssen, da auf einmal 2 RadioButtons hinzukommen.
		    	   */  
	    		  if (parser.getAttributeLocalName( 0 ).equals("name")){
	    			  String frage = parser.getAttributeValue( 0 );
	    			  System.out.println( spacer + "  yesno");
	    			  al_typ.add("yesno");
	    			  al_typ.add(null); //Muss auch abgefangen werden
    				  al_name.add(frage);
    				  al_name.add(null);
    				  al_jPanel.add(null);
    				  al_jPanel.add(null);
    				  //al_jText.add(new JTextField(parser.getAttributeValue(1)));
    				  al_jRadioButton.add(new JRadioButton( "Ja" )); //Vorletztes
    				  al_jRadioButton.add(new JRadioButton( "Nein" )); //Letztes
    				  al_jText.add(new JTextField());
    				  
    				  //Textfeld befüllen falls vorhanden
    				  String textYN = parser.getElementText();
    				  String[] inhalt;
    				  if (!textYN.equals("")){
    					  inhalt =  textYN.split(";;"); //Stream splitten
    					  if (inhalt.length > 0){
    						  if(inhalt.length > 1){//Abfangen wenn kein Text
    							  textYN = inhalt[1];
    						  }else{textYN="";}
    					  
    						  if (inhalt[0].equals("yes")){
    							  al_jRadioButton.get(al_jRadioButton.size()-2).setSelected(true); //Vorletztes Element
    						  }	
    						  else if(inhalt[0].equals("no")){
    							  al_jRadioButton.get(al_jRadioButton.size()-1).setSelected(true);
    						  }
    						  else{//Abfangen wenn nur Text
    							  if (inhalt.length == 1){
    								  textYN = inhalt[0];
    							  }
    						  }
    						  //al_jText.get(al_jText.size()-1).setText(inhalt[1]); //GEHT
    						  al_jText.get(al_jText.size()-1).setText(textYN);
    					  }
    				  }
    				  }
  
    				  al_jText.add(null);
    				  al_jTextArea.add(null);
    				  al_jTextArea.add(null);
    				  al_jCheckBox.add(null);
    				  al_jCheckBox.add(null);
    				  
	    	  }		    	  	      
		      
 
		      else{
		    	  for ( int i = 0; i < parser.getAttributeCount(); i++ ) 
				        System.out.println( spacer + "  Attribut: " 
				                            + parser.getAttributeLocalName( i ) 
				                            + " Wert: " + parser.getAttributeValue( i ) );
		      }
		 
		       
		      break; 
		 
		    case XMLStreamConstants.END_ELEMENT: 
		      System.out.println( spacer + "END_ELEMENT: " + parser.getLocalName() ); 
		      spacer.delete( (spacer.length() - 2), spacer.length() ); 
		      break; 
		 
		    default: 
		      break; 
		  } 
		  parser.next(); 
		}
```

Bei einem attribut Textfeld geht es nicht, aber in yesno geht es komischerweise.

Beispiel XML:

[XML]
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<protokoll_style version="1" datum="31.12.01"> 

  <seite name="1. Gesamteindruck">
  <attribut name="1.1 Grundstimmung" typ="textfeld">Text</attribut>
      <yesno name="Fröhlich"></yesno>
  </seite>
</protokoll_style>
[/XML]

Als exception bekomme ich, aber nur wenn ich es bei dem attribut Textfeld mache:

Exception in thread "main" java.lang.IllegalStateException: Current state is not among the states START_ELEMENT , ATTRIBUTEvalid for getAttributeCount()
	at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.getAttributeCount

Warum ???:L

Viele Grüße Kay


----------



## kayf (23. Mrz 2011)

Ich habe Da etwas gefunden verstehe es nur nicht ganz und zwar auf dieser Seite:
Anil's Technical Blog: Error: elementGetText() function expects text only elment but START_ELEMENT was encountered

Da steht:


> It means that your STAX based parser is not handling the embedded xml properly. Your parser is expecting a regular text element and doing XMLEventReader.getElementText() call.
> 
> Solutions:
> 1) Bad: You can convert all "<" of your embedded xml to & l t ; (characters brought together).
> 2) Good: Let the parser peek at the next event and see if it is embedded xml and handle properly.



Nummer eins verstehe ich, aber das möchte ich so nicht machen.
Was meint er genau mit Nummer 2???:L


----------



## kayf (25. Mrz 2011)

letzter Push!
Hat denn wirklich Keiner eine Idee?


----------



## mvitz (25. Mrz 2011)

Doch, sogar die Lösung.

Die API von getElementText() sagt hier eindeutig folgendes:



> Precondition: the current event is START_ELEMENT.
> Postcondition: the current event is the corresponding END_ELEMENT.



D.h. nachdem du getElementText aufgerufen hast, bist du im Zustand END_ELEMENT.

getAttributeCount() sagt jedoch:



> Returns the count of attributes on this START_ELEMENT, this method is only valid on a START_ELEMENT or ATTRIBUTE.



D.h. nachdem du getElementText() aufgerufen hast, darfst du getAttributeCount() nicht mehr aufrufen!

Eine mögliche Lösung ist folgende:


```
...
else if (elementName.equals("attribut")){
  String print ="";
  int numberOfAttributes = parser.getAttributeCount();
  for ( int i = 0; i < numberOfAttributes; i++ ) {
    String attributName = parser.getAttributeLocalName(i);
    String attributWert = parser.getAttributeValue(i);
...
```

EDIT: Wobei mir gerade auffällt, dass du auch getAttributeLocalName und getAttributeValue danach nicht mehr aufrufen darfst, d.h. du bekommst ein Problem, sobald "typ" nicht mehr das letzte Attribut ist... Hierfür wäre vermutlich dann die Lösung, dass du getElementText erst aufrufen darfst, nachdem du ALLE Attribute ausgelesen hast.


----------



## kayf (25. Mrz 2011)

Man Danke! 
Ich habe es jetzt zwar auch schon anders gebaut, aber ich habe den Fehler jetzt richtig verstanden.
Danke!:toll:

Meine Lösung ist jetzt: 
Ich habe keine Attribut-Elemente mehr für Textfeld und Textarea, sondern eigene Elemente, also <textarea></textarea> und <textfield></textfield>. Somit muss ich die von dir genannten Daten nicht mehr lesen. Ist so, sowieso viel schöner.

Evtl. poste ich das Ergebnis nochmal.


----------

