# XML Editor im Project



## Koringar (29. Sep 2009)

Hi,

ich will in meinem jetzigen Projekt kein in RCP ein XML Editor haben, dem eben ein String im XML Format übergeben werden kann.
Es gibt von Eclipse ja diesen XML Editor schon, weis einer wie ich den Einbinden kann oder eventuell auch verändern/ erweitern? Ich weis das man dafür die WST.XML Plugin's braucht, mehr aber auch nicht.

Würde mich freuen wenn einer schon Erfahrung damit hat, denn eventuell würde ich gern auch als View und nicht als Editor haben.

MfG


----------



## Gonzo17 (29. Sep 2009)

Ich hab das mal so gemacht:


```
public class MyXMLEditor extends XMLMultiPageEditorPart {
//...
}
```

In der plugin.xml unter "Extensions" dann noch eine Extension "org.eclipse.ui.editors" hinzugefügt und dort eben dann meinen XML-Editor. Hoffe das hilft dir mal für den Anfang.


----------



## Koringar (29. Sep 2009)

Danke für die Antwort, aber was ich so von dem XMLMultiPageEditorPart gesehen habe ist das eine Art TextEditor ich würde aber gern diese TreeStruktur haben.

Ich habe das jetzt auch hinbekommen, in dem man in der View das Widget 'XMLTableTreeViewer' benutzt. Bei 'setInput' erwartet er ein Object vom Typ 'org.w3c.dom.Document' und das funktioniert auch alles super, er liest da wirklich alles aus.
Ich habe blos gerade eine anderes Problem das er bei Parsen über den DomParser mir nicht den Inhalt der Tags ausgeben will (auch über das manuelle abrufen über den Code des Document kommt null raus). Ich versuche das gerade noch irgendwie hinzubekommen.


----------



## Koringar (30. Sep 2009)

Also das mit dem 'setInput' funktioniert deshalb nicht, da der XMLTableTreeViewer über 'setDocument' mit Inhalt befüllt werden soll. Beim normalen setInput setzt er automatisch ein internes Flag und gibt den Inhalt der Tags z.B. nicht aus.
Wenn man den Inhalt aber über ein IDocument setzt sollte es klappen.

Jedoch habe ich jetzt das Problem, wie komme ich an dieses ran? Der Inhalt ist keine Datei die irgend woe liegt sondern ist ein InputStream den ich von einer DB bekomme.

Hat vielleicht jemand eine Ahnung wie ich aus einem InputStream ein Object von org.eclipse.jface.text.IDocument mache???


----------



## Koringar (1. Okt 2009)

Hi Gonzo,

nach langem hin und her will ich jetzt einfach mal mit dem kompletten XMLMultipageEditor probieren. Wie setzte ich den Input des Editor, ich porbiere das immer so
	
	
	
	





```
{
						IPath filepath = new  Path("GUI(RCP)/config/test.xml");
						System.out.println(filepath.toOSString());
						IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(filepath);
						System.out.println(file.exists());						
						IEditorInput input = new FileEditorInput(file);
						page.openEditor(input, "org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorPart");
```
jedoch sagt es immer wieder das File würde nicht existieren.


----------



## Koringar (2. Okt 2009)

Hi,

so nach einigen verzweifelten Versuchen, habe ich es nun hinbekommen das die XML angezeigt wird. Und das in einem Viewer und nur die TreeAnsicht der XML.

Im Grunde ist es ziehmlich einfach dies umzusezten, je nachdem was man als Ausgangspunkt hat verwendetet am als Baum den normalen TreeViewer oder den XMLTableTreeViewer von org.eclipse.wst.xml.ui .

Den normalen TreeViewer verwendet man am besten wenn man nur das XML Dokument als org.w3c.dom.Document vorliegen hat, diesem TreeViewer setzt man als Label und ContentProvider den XMLTableTreeContentProvider und es sollte alles fast funktionieren. Bei mir hat er noch eine CastException geschmiesen als ich die Textelemete haben wollte. Deshalb musst ich da noch etwas am Provider und seiner Helferklasse TreeContentHelper. Die Helperklasse musste nur die Methode 'getValueForTextContent' angepasst werden (Code follgt) und im Provider einfach nur der verweis auf die richtige Helperklasse. Damit man es besser sehen kann hier nochmal denn Code.


```
public class XMLViewer extends ViewPart{
       private TreeViewer xmlAnzeigeFeld;
	private Tree xmlTree;
	
	private Document doc = null;
	
	@Override
	public void createPartControl(Composite parent) {
		xmlAnzeigeFeld = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.VIRTUAL | SWT.FULL_SELECTION);
		XMLTableTreeContentProvider provider = new XMLTableTreeContentProvider();
		xmlAnzeigeFeld.setContentProvider(provider);
		xmlAnzeigeFeld.setLabelProvider(provider);
		xmlTree = xmlAnzeigeFeld.getTree();
		
		createColumHeader();
	}
       private void createColumHeader() {
		if (logger.isDebugEnabled())
			logger.debug("Erstelle den Tabellenkopf");
		TreeColumn colMonitor = new TreeColumn(xmlTree, SWT.LEFT);
		colMonitor.setText("Tags");
		colMonitor.setWidth(400);
		colMonitor = new TreeColumn(xmlTree, SWT.LEFT);
		colMonitor.setText("Inhalt");
		colMonitor.setWidth(500);
	}
       public void setInput(InputStream pProtokoll, String pUeberschrift){
		
		if(pProtokoll != null && pUeberschrift != null){
			setPartName(pUeberschrift);			
			try {
				DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
				DocumentBuilder builder = factory.newDocumentBuilder(); 
				doc = builder.parse(pProtokoll);				
				xmlAnzeigeFeld.setInput(doc);
			} catch (SAXException e) {
				e.printstacktrace;
			} catch (IOException e) {
				e.printstacktrace;
			} catch (ParserConfigurationException e) {
				e.printstacktrace;
			}
		}else if(pUeberschrift != null){
			setPartName(pUeberschrift);
			xmlAnzeigeFeld.setInput(null);
		}else{
			xmlAnzeigeFeld.setInput(null);
		}
	}
}
```


```
public class XMLTableTreeContentProvider extends org.eclipse.wst.xml.ui.internal.tabletree.XMLTableTreeContentProvider {
	
	private TreeContentHelper treeContentHelper = new TreeContentHelper();
	
	@Override
	public String getColumnText(Object object, int column) {
		String result = null;
		if (column == 0) {
			result = getText(object);
		}
		else if (column == 1 && object instanceof Node) {
			result = treeContentHelper.getNodeValue((Node) object);
		}
		return result != null ? result : ""; //$NON-NLS-1$
	}
}
```


```
public class TreeContentHelper extends
		org.eclipse.wst.xml.ui.internal.tabletree.TreeContentHelper {
	
	@SuppressWarnings("unchecked")
	@Override
	protected String getValueForTextContent(List list) {
		String result = null;
		if (list.size() > 0) {
			DeferredTextImpl first = (DeferredTextImpl) list.get(0);
			result = first.getNodeValue();
//			Das hat die CastException geschmiesen.
//			IDOMNode first = (IDOMNode) list.get(0);
//			IDOMNode last = (IDOMNode) list.get(list.size() - 1);
//			IDOMModel model = first.getModel();
//			int start = first.getStartOffset();
//			int end = last.getEndOffset();
//			try {
//				result = model.getStructuredDocument().get(start, end - start);
//			} catch (Exception e) {
//			}
		}

		// we trim the content so that it looks nice when viewed
		// we need to be carfull to preserve the 'trimmed' text when the value
		// is set (see setValueForTextContent)
		if (result != null) {
			result = result.trim();
		}
		return result;
	}
}
```

Wenn man als InputType ein org.eclipse.jface.text.IDocument hat, sollte man den Ursprünglichen XMLTableTreeViewer und seine Klasse verwenden (also nichts anpassen). Jedoch hat ich keine Ahnung wie ich aus dem InputStream ein IDocument machen sollte. Außerdem kam es beim Verwenden des XMLTableTree zu Fehler beim Schließen der View.
Man kann zwar den Inhalt des XMLTableTree auch mit setInput setzten, da wird zwar auch das org.w3c.dom.Document erwartet, jedoch setzt er ein Inteneres Falg was verhindert das der Inhalt der Tags ausgelesen wird. Da es ein im unbekanntes Dokument ist und eben diese CastException sonst schmeißen würde, des wegen muss man den Inhalt über setDocument da setzten.

Ich hoffe ich konnte damit jetzt einigen weiter helfen, mir hat es sehr viel Kopfverbrechen bereitet.

MfG Koringar

Edit: Hierbei handelt es sich nur um eine Anzeige der XML, keine bearbeitung.

Edit2: Die abhängigen Plug-Ins sind 
org.eclipse.wst.xml.ui
org.eclipse.wst.xml.core


----------



## Gonzo17 (2. Okt 2009)

Schön, dass du es noch lösen konntest, hatte gestern keine Zeit mehr dir zu schreiben, aber wenn es jetzt klappt, ist ja umso besser. :toll:


----------



## Koringar (2. Okt 2009)

Kannste aber trotzdem mal das mit den EditorInput setzten posten, würde mich gern interessieren wie das bei dem PlugIn geht. Danke schon mal für die Mühe.


----------



## Gonzo17 (2. Okt 2009)

Also wie oben angedeutet hab ich ja daraus meinen eigenen XML-Editor gebastelt und am Input hab ich rein garnichts verändert. Funktioniert so, wie es vorher schon war. Ich hab auch in der init-Methode diesbezüglich nichts geändert, nur ein paar andere Sachen hinzugefügt. Weiss also nicht, weshalb es bei dir nicht funktioniert. ???:L

Ich schätze mal er schmeisst dir ne Exception, wenn es nich klappt. Wie genau sieht die Exception aus? Haste mal debuggt und bist da an die genaue Stelle gesprungen?


----------



## Koringar (2. Okt 2009)

Er schmeißt immer die FileNotFoundException, ich habe keine Ahnung warum. Ich habe schon zichtausendmal versucht den Pfad zuänder, immer das selber Ergebnis.

Das komische ist aber auch wenn ich filepath.exit() mache sagt er true, nach dem ich mir aber das IFile gegeben haben lasse und dann wieder mit file.exist() prüfe sagt er false ???:L .


----------



## Gonzo17 (2. Okt 2009)

Dann liegt es wohl IFile und nicht am XML-Editor. Vielleicht solltest du, um sicherzugehen, dass das File auch wirklich da liegt, mal einen Dialog vorschalten, in dem du das File auswählst. Nur um zu testen, ob es dann klappen würde.


----------



## Koringar (2. Okt 2009)

Ich weis nicht, ich würde eher vermuten das es daran liegt 
'IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(filepath);' das er damit auf irgend ein Verzeichniss geh, ka welches.

Hast du vielleicht einen anderen Weg sich von IPath (oder String) das IFile gebenlassen kann.


----------



## Gonzo17 (2. Okt 2009)

Achso klar, das kann sein. Aber da hab ich leider grad garkeine Idee, wie man das lösen könnte. :bahnhof:


----------

