XPath Adressierung

Status
Nicht offen für weitere Antworten.

NNiko

Mitglied
Hallo ich habe ein Problem mit der Adressierung bei XPath.

Mit folgendem Stück Code

Java:
XPathExpression expr = xpath.compile("//MAPPINGTABLES//MAPPINGTABLE//MAPPING//text()");

will ich den Inhalt der MAPPING Tags folgender XML Datei bearbeiten

[XML]
<?xml version="1.0" encoding="UTF-8" standalone="no"?><MMI>
<MAPPINGTABLES>
<MAPPINGTABLE hash="key" name="ack_caption_job_2" type="map">
<MAPPING key="0">TEST</MAPPING>
<MAPPING key="1">TEST</MAPPING>
<MAPPING key="2">TEST</MAPPING>
<MAPPING key="3">TEST</MAPPING>
<MAPPING key="4">TEST</MAPPING>
<MAPPING key="5">TEST</MAPPING>
<MAPPING key="6">TEST</MAPPING>
<MAPPING key="7">TEST</MAPPING>
<MAPPING key="8">TEST</MAPPING>
<MAPPING key="9">TEST</MAPPING>
<MAPPING key="10">TEST</MAPPING>
<MAPPING key="11">TEST</MAPPING>
<MAPPING key="12">TEST</MAPPING>
<MAPPING key="13">TEST</MAPPING>
<MAPPING key="14">TEST</MAPPING>
<MAPPING key="15">TEST</MAPPING>
<MAPPING key="16">TEST</MAPPING>
<MAPPING key="-1">TEST</MAPPING>
<MAPPING key="default"/>
</MAPPINGTABLE>



</MAPPINGTABLES>
</MMI>[/XML]

Mein Code lässt mich soweit auch den Inhalt zwischen allen MAPPING Tags (in dem Fall Test) bearbeiten und ändern. Jedoch würde ich gerne in jede Zeile etwas anderes schreiben und hoffte nun ich kann das mit XPath so addressieren, dass er mir das MAPPING Tag adressiert, welches z.B. den key="1" enthält.

Ist sowas irgendwie möglich, ich hab nämlich nix dazu gefunden...
 

Ariol

Top Contributor
Versuchs mal mit
Java:
String key = "3";
XPathExpression expr = xpath.compile("//MAPPINGTABLES//MAPPINGTABLE//MAPPING[@key=\""+key+"\"]//text()");


Und zum finden:
Google-Suche nach "Xpath" -> erster Link (Deutsche Seiten) und du kommst hier raus:
XPath ? Wikipedia
 

NNiko

Mitglied
Jetzt hätt ich aber noch ne ander Frage, vllt kannst du mir das auch noch beantworten.

Dies ist mein Code für das Tag welches ich bearbeiten will:

Java:
...
try {
            builder = factory.newDocumentBuilder();
            Document doc = builder.parse("...//test1.xml");

            XPathFactory factoryX = XPathFactory.newInstance();
            XPath xpath = factoryX.newXPath();
            String key = "0";
            XPathExpression expr = xpath.compile("//MAPPINGTABLES//MAPPINGTABLE//MAPPING[@key=\""+key+"\"]//text()");
            Object result = expr.evaluate(doc, XPathConstants.NODESET);
            NodeList nodes = (NodeList) result;

             for (int i = 0; i < nodes.getLength(); i++) {
                //System.out.println("Alter Wert name: "+nodes.item(i).getNodeValue());
                nodes.item(i).setNodeValue("");
                //System.out.println("Neuer Wert name: "+nodes.item(i).getNodeValue());
             }

Ich will jetzt hintereinander für jedes MAPPING TAG einen anderen Wert eintragen.
Kannst du mir vllt einen Tip geben wie ich das mit diesem Code lösen kann.
Ich kann ja jetzt so einfach keinen weiteren key als String definieren, oder?

Grüße
 

NNiko

Mitglied
Also ich habe vor aus einer Datei A einen bestimmten Wert auszulesen. Wenn dieser Wert gefunden wird, dann soll er in Datei B an die bestimmte Stelle etwas eintragen.

Was ich bisher gefixed habe ist:
Datei A öffnen bestimmten Wert auslesen.
Datei B öffnen einen Wert an die bestimmte Stelle schreiben.

Jetzt will ich das ganze Verknüpfen. Ich sollte mehrere Werte aus Datei A auslesen und in Datei B an verschiede Stellen dann einen Text einfügen.

Mein Code:

Java:
 import java.io.*;
 import javax.xml.parsers.*;
 import org.w3c.dom.*;
 import org.w3c.dom.NodeList;
 import org.w3c.dom.Node;
 import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.Source;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

  class RC {

    public static void main(String[] args) throws Exception {
       RC theClient = new RC();
       theClient.run();
    }
    int name;
    private void run() throws Exception {

      if (name <1) {

       File xmlFile = null;
       xmlFile = new File( "...//statemachine.xml" );

       DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
       DocumentBuilder builder = factory.newDocumentBuilder();

       Document doc = builder.parse( xmlFile );


       NodeList nodeList = doc.getElementsByTagName( "UML:SimpleState" );

      

       Node firstNode = nodeList.item(0);
       NamedNodeMap nodemap = firstNode.getAttributes();


       
       System.out.println( nodemap.getNamedItem( "name" ).getNodeValue() );
      
       
       System.out.println( nodemap.getNamedItem( "outgoing" ).getNodeValue() );
       System.out.println( nodemap.getNamedItem( "incoming" ).getNodeValue() );
      
     } else {System.out.println("Keine Dateien Vorhanden");

     }
     
     String name = "NEUER_AUFTRAG"; 
      
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true); // never forget this!
        DocumentBuilder builder;
        try {
            builder = factory.newDocumentBuilder();
            Document doc = builder.parse("...Test1.xml");

            XPathFactory factoryX = XPathFactory.newInstance();
            XPath xpath = factoryX.newXPath();
            String key = "0";
            XPathExpression expr = xpath.compile("//MAPPINGTABLES//MAPPINGTABLE//MAPPING[@key=\""+key+"\"]//text()");
            Object result = expr.evaluate(doc, XPathConstants.NODESET);
            NodeList nodes = (NodeList) result;

             for (int i = 0; i < nodes.getLength(); i++) {
                System.out.println("Alter Wert name: "+nodes.item(i).getNodeValue());
                nodes.item(i).setNodeValue(name);
                System.out.println("Neuer Wert name: "+nodes.item(i).getNodeValue());
             }

             TransformerFactory.newInstance().newTransformer().transform(
             new DOMSource(doc), new StreamResult(...Test1.xml")));
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (XPathExpressionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch( TransformerConfigurationException tce ) {
            System.out.println( "\n** Transformer Factory error" );
            System.out.println( "   " + tce.getMessage() );
            Throwable e = ( tce.getException() != null ) ? tce.getException() : tce;
            e.printStackTrace();
        } catch( TransformerException tfe ) {
            System.out.println( "\n** Transformation error" );
            System.out.println( "   " + tfe.getMessage() );
            Throwable e = ( tfe.getException() != null ) ? tfe.getException() : tfe;
            e.printStackTrace();

        }


    }
 }

Ich lese jetzt aus einer xml Datei eine Zeile aus und lasse mir diese Anzeigen. Jetzt sollte aber das was er hier ausließt den Anstoß geben, dass er das was ich als "String name" definiert habe in Datei Test1 an die bestimmte Stelle schreibe.

Wenn dies klappt, dann kann ich schon mal einen Wert aus Datei A lesen und dann einen vorgegebenen Text (in dem Fall String name = NEUER AUFTRAG) in Datei B an die Stelle bei key="0" schreiben.

Ich sollte aber insgesammt 16 Werte aus Datei A lesen und sie in bestimmte Felder in XML Datei B schreiben.
 

Ariol

Top Contributor
Java:
import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class RC
{
	private final String	stateFile	= "..Test1.xml";

	public static void main(String[] args) throws Exception
	{
		RC theClient = new RC();
		theClient.run();
	}

	private void run()
	{
		File xmlFile = new File("...//statemachine.xml");
		processFile(xmlFile);
	}

	private boolean processFile(File xmlFile)
	{
		System.out.println("Bearbeite \"" + xmlFile.getName() + "\"...");
		try
		{
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
	
			Document doc = builder.parse(xmlFile);
	
			NodeList nodeList = doc.getElementsByTagName("UML:SimpleState");

			for (int i = 0; i < nodeList.getLength(); i++)
			{
				NamedNodeMap nodemap = nodeList.item(i).getAttributes();
				String name = nodemap.getNamedItem("name").getNodeValue();
				String incoming = nodemap.getNamedItem("incoming").getNodeValue();
				String outgoing = nodemap.getNamedItem("outgoing").getNodeValue();
				System.out.println(name + "\n" + incoming + "/" + outgoing);	
				setState(name, "NEUER_AUFTRAG");
			}
			System.err.println("Bearbeiten von \"" + xmlFile.getName() + "\" abgeschlossen!");
			return true;
		}
		catch (Exception e) {
			System.err.println("Bearbeiten von \"" + xmlFile.getName() + "\" fehlgeschlagen: " + e);
		}
		return false;
	}

	private void setState(String key, String newState) throws Exception
	{
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(true); // never forget this!
		DocumentBuilder builder;
		Document doc;

		builder = factory.newDocumentBuilder();
		doc = builder.parse(stateFile);

		XPathFactory factoryX = XPathFactory.newInstance();
		XPath xpath = factoryX.newXPath();
		XPathExpression expr = xpath.compile("//MAPPINGTABLES//MAPPINGTABLE//MAPPING[@key=\"" + key + "\"]//text()");
		Object result = expr.evaluate(doc, XPathConstants.NODESET);
		NodeList nodes = (NodeList) result;

		for (int i = 0; i < nodes.getLength(); i++)
		{
			System.out.println("Alter Wert name: " + nodes.item(i).getNodeValue());
			nodes.item(i).setNodeValue(newState);
			System.out.println("Neuer Wert name: " + nodes.item(i).getNodeValue());
		}

		TransformerFactory.newInstance().newTransformer().transform(new DOMSource(doc), new StreamResult(stateFile));

	}
}
 
Zuletzt bearbeitet:

NNiko

Mitglied
Danke, du bist genial!
Jetzt kann ich schon mal alle wichtigen Dateien auslesen, aber leider schreibt er die Daten jetzt nicht in die gewünschte Datei.
 
Zuletzt bearbeitet:

Ariol

Top Contributor
Versuchs mal so:
Java:
import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;

public class RC
{
	private final String	stateFile	= "..Test1.xml";
	private DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

	private XPathFactory factoryX = XPathFactory.newInstance();
	private XPath xpath = factoryX.newXPath();
	
	public static void main(String[] args) throws Exception
	{
		RC theClient = new RC();
		theClient.run();
	}

	private void run()
	{
		File xmlFile = new File("...//statemachine.xml");
		processFile(xmlFile);
	}

	private boolean processFile(File xmlFile)
	{
		System.out.println("Bearbeite \"" + xmlFile.getName() + "\"...");
		try
		{
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document inDoc = builder.parse(xmlFile);
			NodeList nodeList = inDoc.getElementsByTagName("UML:SimpleState");
			
			factory.setNamespaceAware(true); // never forget this!
			Document outDoc = builder.parse(stateFile);


			for (int i = 0; i < nodeList.getLength(); i++)
			{
				NamedNodeMap nodemap = nodeList.item(i).getAttributes();
				String name = nodemap.getNamedItem("name").getNodeValue();
				String incoming = nodemap.getNamedItem("incoming").getNodeValue();
				String outgoing = nodemap.getNamedItem("outgoing").getNodeValue();
				System.out.println(name + "\n" + incoming + "/" + outgoing);	
				outDoc = setState(outDoc, name, "NEUER_AUFTRAG");
			}

			DOMSource domSource = new DOMSource(outDoc);
		    File fileOutput = new File(stateFile);
		    StreamResult streamResult = new StreamResult(fileOutput);
		    TransformerFactory tf = TransformerFactory.newInstance();

		    Transformer serializer = tf.newTransformer();
		    serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
		    serializer.setOutputProperty(OutputKeys.INDENT, "yes");
		    serializer.transform(domSource, streamResult);
			
			
			System.err.println("Bearbeiten von \"" + xmlFile.getName() + "\" abgeschlossen!");
			return true;
		}
		catch (Exception e) {
			System.err.println("Bearbeiten von \"" + xmlFile.getName() + "\" fehlgeschlagen: " + e);
		}
		return false;
	}

	private Document setState(Document doc, String key, String newState) throws Exception
	{
		XPathExpression expr = xpath.compile("//MAPPINGTABLES//MAPPINGTABLE//MAPPING[@key=\"" + key + "\"]//text()");
		Object result = expr.evaluate(doc, XPathConstants.NODESET);
		NodeList nodes = (NodeList) result;

		for (int i = 0; i < nodes.getLength(); i++)
		{
			System.out.println("Alter Wert name: " + nodes.item(i).getNodeValue());
			nodes.item(i).setNodeValue(newState);
			System.out.println("Neuer Wert name: " + nodes.item(i).getNodeValue());
		}
				
		return doc;


	}
}
 

NNiko

Mitglied
Funktioniert leider immer noch nicht. Er ließt die Daten alle korrekt aus und Zeigt sie an, aber schreiben tut er nix.
Was aber seltsam ist, ist, dass er wenn ich
Java:
XPathExpression expr = xpath.compile("//MAPPINGTABLES//MAPPINGTABLE//MAPPING[@key=\"" + key + "\"]//text()");
so durchlaufen lasse, alle Daten ausließt, aber wenn ich es so eingebe
Java:
XPathExpression expr = xpath.compile("C://Dokumente und Einstellungen//nuesslen//Eigene Dateien//Eigene Bilder//Praxisarbeit//statemachine.xml//MAPPINGTABLES//MAPPINGTABLE//MAPPING[@key=\"" + key + "\"]//text()");
ließt er nur den erste Datensatz aus und gibt dann die Fehlermeldung Bearbeiten Fehlgeschlagen aus
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben