Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/corpus/Metadata2TeiHeaderMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/corpus/Metadata2TeiHeaderMacro.groovy	(revision 1971)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/corpus/Metadata2TeiHeaderMacro.groovy	(revision 1972)
@@ -7,20 +7,21 @@
 import groovy.transform.Field
 
 import org.txm.importer.StaxIdentityParser
+import org.txm.objects.*
 import org.txm.rcp.swt.widget.parameters.*
 import org.txm.searchengine.cqp.corpus.*
 import org.txm.utils.CsvReader
 import org.txm.utils.io.IOUtils
+import org.txm.scripts.importer.XPathResult
+import javax.xml.xpath.XPathConstants
 
-if (!(corpusViewSelection instanceof CQPCorpus)) {
-	println "** Corpora selection is not a Corpus. Aborting."
-	return;
-}
+@Field @Option(name="defaultTeiHeaderFile", usage="the default teiHeader of texts", widget="FileOpen", required=true, def="defaultTeiHeaderFile.xml")
+def defaultTeiHeaderFile
 
-@Field @Option(name="xpathFile", usage="properties file to redirect metadata column to the teiHeader locations", widget="FileOpen", required=true, def="file.xml")
+@Field @Option(name="xpathFile", usage="properties file to redirect metadata column to the teiHeader locations", widget="FileOpen", required=true, def="xpathFile.properties")
 def xpathFile
 
-@Field @Option(name="metadataFile", usage="the TSV file containing the metadata values per text", widget="FileOpen", required=true, def="file.xml")
+@Field @Option(name="metadataFile", usage="the TSV file containing the metadata values per text", widget="FileOpen", required=true, def="metadataFile.tsv")
 def metadataFile
 
 @Field @Option(name="debug", usage="Show internal variable content", widget="StringArray", metaVar="OFF	ON	ALL	REALLY ALL", required=true, def="OFF")
@@ -30,15 +31,7 @@
 if (debug == "OFF") debug = 0; else if (debug == "ON") debug = 1; else if (debug == "ALL") debug = 2 else if (debug == "REALLY ALL") debug = 3
 
 
-def corpus = corpusViewSelection
-def project = corpus.getProject()
 
-def txmDir = new File(project.getProjectDirectory(), "txm/"+corpus.getID())
-
-if (!txmDir.exists()) {
-	println "** the selected corpus has no XML-TXM files. Aborting."
-}
-
 def xpathProperties = new Properties()
 xpathProperties.load(IOUtils.getReader(xpathFile))
 println xpathProperties
@@ -52,61 +45,170 @@
 	println "** 'id' column not found in $metadataFile"
 	return;
 }
+
+def corpora = [:]
+for (Project project : Workspace.getInstance().getProjects()) {
+	for (MainCorpus corpus : project.getChildren(MainCorpus.class)) {
+		corpora[corpus.getID()] = corpus;
+	}
+}
+
 while (csvReader.readRecord())	{
 	String text_id = csvReader.get("id")
 	if (text_id == null || text_id.length() == 0) {
-		println "** @id not found for record="+csvReader.getRawRecord()
+		//println "** @id not found for record="+csvReader.getRawRecord()
 		continue;
 	}
+	
+	String corpus_id = csvReader.get("corpus_id")
+	if (corpus_id == null || corpus_id.length() == 0) {
+		println "** @corpus_id not found for record="+csvReader.getRawRecord()
+		continue;
+	}
+	
+	MainCorpus corpus = corpora[corpus_id]
+	if (corpus == null) {
+		println "** no corpus found for ID=$corpus_id"
+		continue;
+	}
+	def project = corpus.getProject()
+	
+	def txmDir = new File(project.getProjectDirectory(), "txm/"+corpus.getID())
+	
+	if (!txmDir.exists()) {
+		println "** the selected corpus has no XML-TXM files. Aborting."
+	}
+	
+	
 	File txmFile = new File(txmDir, text_id+".xml")
 	if (txmFile.exists()) {
 		
 		def data = [:]
 		for (def h : header) data[h] = csvReader.get(h)
 			
-		injecting(txmFile, data, xpathProperties)
+		String xmlteiHeaderContent = getCustomizedTEiHeader(defaultTeiHeaderFile, data, xpathProperties);
+		if (xmlteiHeaderContent != null && xmlteiHeaderContent.length() > 0) {
+			injecting(txmFile, xmlteiHeaderContent)
+		} else {
+			println "** Text header not updated: $txmFile"
+		}
 	} else {
 		println "** Text not found: $txmFile"
 	}
 }
 
-def injecting(File txmFile, def data, def paths) {
+def getCustomizedTEiHeader(File defaultTeiHeaderFile, def data, Properties xpathProperties) {
+	XPathResult xpathProcessor = new XPathResult(defaultTeiHeaderFile);
+	for (String info : data.keySet()) {
+		String xpath = xpathProperties[info];
+		String value = data[info]
+		if (xpath == null) {
+			continue; // not a data to inject
+		}
+		if (debug > 1) println "   injecting '$info'='$value' in '$xpath'"
+		
+def expr = xpathProcessor.xpath.compile(xpath);
+def first = expr.evaluate(xpathProcessor.doc.getDocumentElement(), XPathConstants.NODE);
+		if (first != null) {
+			switch (first.getNodeType()) {
+				case 1: // element
+					if (debug > 1) println "   patching: $info with "+value
+					def newChild = xpathProcessor.doc.createElement(first.getTagName())
+					newChild.appendChild(xpathProcessor.doc.createTextNode(value))
+					first.getParentNode().replaceChild(newChild, first)
+					break;
+				case 2: // attribute
+					if (debug > 1) println "   patching attribute: $info with "+value
+					first.setNodeValue(value)
+					break;
+				case 3: // text
+					if (debug > 1) println "   patching text: $info with "+value
+					first.setNodeValue(value)
+					break;
+				default:
+					break
+			}
+		} else {
+			println "** not found $xpath"
+		}
+	}
+	
+//	return xpathProcessor.doc.getElementsByTagName("teiHeader").item(0).getNodeValue();
+	//println "DOC="+xpathProcessor.doc.getDocumentElement().getElementsByTagName("teiHeader").item(0).toString()
+	String content = ""+xpathProcessor.doc.getDocumentElement().getElementsByTagName("teiHeader").item(0)
+	content = content.substring('<?xml version="1.0" encoding="UTF-8"?>'.length())
+}
+
+/**
+ * Replace the teiHeader 
+ * @param txmFile
+ * @param data
+ * @param paths
+ * @param xmlteiHeaderContent
+ * @return
+ */
+def injecting(File txmFile, String xmlteiHeaderContent) {
 	println "Editing: $txmFile..."
 	StaxIdentityParser sparser = new StaxIdentityParser(txmFile) {
-		String currentXPath = ""
 		boolean start = false;
-		def foundPaths = [:]
 		public void processStartElement() {
-			super.processStartElement();
 			
-			if (localname == "teiHeader") start = true;
-			if (start) {
-				currentXPath += "/"+localname 
-				def attributes = [:]
-				for (int i = 0 ; i < parser.getAttributeCount() ; i++) {
-					attributes[parser.getAttributeLocalName(i)] = parser.getAttributeValue(i);
-				}
-				if (attributes.size() > 0)
-					println currentXPath+attributes
-				else 
-					println currentXPath
+			if (localname == "teiHeader") {
+				start = true;
+				if (debug > 2) println "   replacing teiHeader"
+				if (debug > 3) println "       with $xmlteiHeaderContent"
+				output.write(xmlteiHeaderContent.getBytes(Charset.forName("UTF-8")));  // REPLACE CONTENT !
 			}
+			if (!start) {
+				super.processStartElement();
+			}
 		}
 		
 		public void processEndElement() {
-			super.processEndElement();
-			if (localname == "teiHeader") start = false;
-			if (start) {
-				currentXPath = currentXPath.substring(0, currentXPath.lastIndexOf("/"))
+			if (!start) {
+				super.processEndElement();
 			}
+			if (localname == "teiHeader") {
+				start = false;
+				if (debug > 2) println "   replace done"
+			}
 		}
+		
+		public void processCharacters() {
+			if (!start) {
+				super.processCharacters();
+			}
+		}
+		
+		public void processComment() {
+			if (!start) {
+				super.processComment();
+			}
+		}
 	}
-	File outfile = File.createTempFile("txm", txmFile.getName())
 	
-	boolean ret = sparser.process(outfile);
-	if (ret) { // replace inputFile
+	File tmpDirectory = new File("/home/mdecorde/TEMP");
+	File outfile = new File(tmpDirectory, "tmp_"+txmFile.getName())
+	File copyFile = new File(tmpDirectory, "copy_"+txmFile.getName())
+	
+	if (sparser.process(outfile)) { // replace inputFile
+		if (txmFile.renameTo(copyFile)) {
+			if (outfile.renameTo(txmFile)) {
+				println " -> SUCCESS see $txmFile"
+				return true
+			} else {
+				println " -> FAIL could not replace $txmFile"
+				println " -> see result in $outfile"
+				
+			}
+		} else {
+			println " -> FAIL could not make a copy of $txmFile in $copyFile"
+			println " -> see result in $outfile"
+		}
 		
+	} else {
+		println " -> FAIL see $outfile"
 	}
 	
-	return ret;		
+	return false;		
 }
\ No newline at end of file
Index: tmp/org.txm.core/src/java/org/txm/scripts/importer/XPathResult.groovy
===================================================================
--- tmp/org.txm.core/src/java/org/txm/scripts/importer/XPathResult.groovy	(revision 1971)
+++ tmp/org.txm.core/src/java/org/txm/scripts/importer/XPathResult.groovy	(revision 1972)
@@ -2,28 +2,28 @@
 // Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
 // Lyon 2, University of Franche-Comté, University of Nice
 // Sophia Antipolis, University of Paris 3.
-// 
+//
 // The TXM platform is free software: you can redistribute it
 // and/or modify it under the terms of the GNU General Public
 // License as published by the Free Software Foundation,
 // either version 2 of the License, or (at your option) any
 // later version.
-// 
+//
 // The TXM platform 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 the GNU General Public License for more
 // details.
-// 
+//
 // You should have received a copy of the GNU General
 // Public License along with the TXM platform. If not, see
 // http://www.gnu.org/licenses.
-// 
-// 
-// 
+//
+//
+//
 // $LastChangedDate: 2017-04-11 15:30:35 +0200 (mar. 11 avril 2017) $
 // $LastChangedRevision: 3426 $
-// $LastChangedBy: mdecorde $ 
+// $LastChangedBy: mdecorde $
 //
 package org.txm.scripts.importer;
 
@@ -51,7 +51,7 @@
  * return the id of a bfm tag <milestone/>
  */
 public class XPathResult {
-	
+
 	/** The doc. */
 	Document doc;
 	XPath xpath;
@@ -64,7 +64,7 @@
 	public XPathResult(File xmlfile) {
 		this(xmlfile, true)
 	}
-	
+
 	/**
 	 * Instantiates a new x path result.
 	 *
@@ -74,44 +74,52 @@
 		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 		factory.setXIncludeAware(true);
 		factory.setNamespaceAware(namespaceAware); // never forget this!
-		
+
 		DocumentBuilder builder = factory.newDocumentBuilder();
 		doc = builder.parse(xmlfile);
-		
+
 		XPathFactory xfactory = XPathFactory.newInstance();
 		xpath = xfactory.newXPath();
 		xpath.setNamespaceContext(new PersonalNamespaceContext());
 	}
-	
+
+	public Document getDocument() {
+		return doc;
+	}
+
 	public def getNodes(String query) {
 		def rnodes = [];
-		
+
 		XPathExpression expr = xpath.compile(query);
 		Object result = expr.evaluate(doc.getDocumentElement(), XPathConstants.NODESET);
-		
-		NodeList nodes = (NodeList) result;
-		for (int i = 0; i < nodes.getLength(); i++) {
-			rnodes.add(nodes.item(i));
+		if (result instanceof NodeList) {
+			NodeList nodes = (NodeList) result;
+			for (int i = 0; i < nodes.getLength(); i++) {
+				rnodes.add(nodes.item(i));
+			}
+		} else {
+			result.getClass()
+			rnodes << result
 		}
 		return rnodes;
 	}
-	
+
 	public String getXpathResponse(String query) {
 		XPathExpression expr = xpath.compile(query);
 		Object result = expr.evaluate(doc.getDocumentElement(), XPathConstants.NODESET);
-		
+
 		NodeList nodes = (NodeList) result;
 		for (int i = 0; i < nodes.getLength(); i++) {
 			//println nodes.item(i)
 			return (nodes.item(i).getNodeValue());
 		}
 	}
-	
+
 	public ArrayList<String> getXpathResponses(String query) {
 		ArrayList<String> xresult = new ArrayList<String>();
 		XPathExpression expr = xpath.compile(query);
 		Object result = expr.evaluate(doc.getDocumentElement(), XPathConstants.NODESET);
-		
+
 		NodeList nodes = (NodeList) result;
 		for (int i = 0; i < nodes.getLength(); i++) {
 			//println nodes.item(i)
@@ -119,23 +127,21 @@
 		}
 		return xresult
 	}
-	
+
 	public String getXpathResponse(String query, String devaultValue) {
 		String rez = getXpathResponse(query);
 		if (rez == null)
 			return devaultValue;
 		return rez;
 	}
-	
+
 	public void close() {
 		xpath = null;
 		doc = null;
 	}
 
 	/**
-
 	 * OBSOLETE VERSION FOR TXM return the node text content given a XPath
-
 	 * "//path.../.../@attr"
 	 * 
 	 * @param path
@@ -164,14 +170,14 @@
 	 * 
 	 * } return ""; }
 	 */
-	
+
 	static public String getXpathResponse(File xmlfile, String query, String devaultValue) {
 		String rez = getXpathResponse(xmlfile, query);
 		if (rez == null)
 			return devaultValue;
 		return rez;
 	}
-	
+
 	static public String getXpathResponse(File xmlfile, String query, String devaultValue, boolean namespaceAware) {
 		String rez = getXpathResponse(xmlfile, query, namespaceAware);
 		if (rez == null)
@@ -189,7 +195,7 @@
 	static public String getXpathResponse(File xmlfile, String query) {
 		return getXpathResponse(xmlfile, query, true);
 	}
-	
+
 	/**
 	 * Gets the xpath response.
 	 *
@@ -200,24 +206,24 @@
 	static public String getXpathResponse(File xmlfile, String query, boolean namespaceAware) {
 		XPathResult result = new XPathResult(xmlfile);
 		return result.getXpathResponse(query);
-//		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-//		factory.setNamespaceAware(namespaceAware); // never forget this!
-//		
-//		DocumentBuilder builder = factory.newDocumentBuilder();
-//		Document doc = builder.parse(xmlfile);
-//		
-//		XPathFactory xfactory = XPathFactory.newInstance();
-//		XPath xpath = xfactory.newXPath();
-//		xpath.setNamespaceContext(new PersonalNamespaceContext());
-//		
-//		XPathExpression expr = xpath.compile(query);
-//		Object result = expr.evaluate(doc, XPathConstants.NODESET);
-//		
-//		NodeList nodes = (NodeList) result;
-//		println "size: "+result.getLength()
-//		for (int i = 0; i < nodes.getLength(); i++) {
-//			return (nodes.item(i).getNodeValue());
-//		}
+		//		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+		//		factory.setNamespaceAware(namespaceAware); // never forget this!
+		//
+		//		DocumentBuilder builder = factory.newDocumentBuilder();
+		//		Document doc = builder.parse(xmlfile);
+		//
+		//		XPathFactory xfactory = XPathFactory.newInstance();
+		//		XPath xpath = xfactory.newXPath();
+		//		xpath.setNamespaceContext(new PersonalNamespaceContext());
+		//
+		//		XPathExpression expr = xpath.compile(query);
+		//		Object result = expr.evaluate(doc, XPathConstants.NODESET);
+		//
+		//		NodeList nodes = (NodeList) result;
+		//		println "size: "+result.getLength()
+		//		for (int i = 0; i < nodes.getLength(); i++) {
+		//			return (nodes.item(i).getNodeValue());
+		//		}
 	}
 
 	/**
@@ -227,9 +233,11 @@
 	 */
 	public static void main(String[] args) {
 		println("main of XPathResult")
-		File xmlFile = new File("/home/mdecorde/TXM/corpora/superphenix/txm/SUPERPHENIX/CreysSuper_04_0175.xml")
-		String value = XPathResult.getXpathResponse(xmlFile, "TEI/text/@date");
-		println "value: $value"
+		File xmlFile = new File("/home/mdecorde/runtime-rcpapplication.product/corpora/DEMOCRATLYON3/txm/DEMOCRATLYON3/DiderotEssais.xml")
+		XPathResult processor = new XPathResult(xmlFile)
+		for (def node : processor.getNodes(xmlFile, "TEI/text/@date")) {
+			println "node: $node"
+		}
 		//value = XPathResult.getXpathResponse(new File("/home/mdecorde/xml/bfm/strasb.xml"), "tei:TEI/tei:teiHeader/tei:revisionDesc/tei:change[contains(.,'étiquetage morpho')]");
 		//println "value: $value"
 	}
