/** * $Id: xpwd.java 21 2008-07-04 08:33:47Z daldei $ * $Date: 2008-07-04 04:33:47 -0400 (Fri, 04 Jul 2008) $ * */ package org.xmlsh.internal.commands; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.List; import javax.xml.namespace.QName; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.xmlsh.core.InputPort; import org.xmlsh.core.Options; import org.xmlsh.core.XCommand; import org.xmlsh.core.XValue; import org.xmlsh.core.io.OutputPort; import org.xmlsh.sh.shell.SerializeOpts; import org.xmlsh.sh.shell.Shell; import org.xmlsh.util.INamingStrategy; import org.xmlsh.util.Util; import org.xmlsh.util.commands.CSVFormatter; import org.xmlsh.util.commands.CSVRecord; import net.sf.saxon.s9api.Processor; import net.sf.saxon.s9api.SaxonApiException; import net.sf.saxon.s9api.XQueryCompiler; import net.sf.saxon.s9api.XQueryEvaluator; import net.sf.saxon.s9api.XQueryExecutable; import net.sf.saxon.s9api.XdmItem; import net.sf.saxon.s9api.XdmNode; /* * * Convert XML files to an CSV file * * Arguments * * -header Add a header row * * */ public class xml2csv extends XCommand { private boolean bHeader = false; private String mRowXpath = "/*/*"; private String mFieldXPath = "*/string()"; private String mHeaderXPath = "*/node-name()"; private boolean bAttr = false; private XQueryCompiler mCompiler; INamingStrategy mNamingStrategy; private static Logger mLogger = LogManager.getLogger(); @Override public int run(List<XValue> args) throws Exception { Options opts = new Options( "nameing=nameing-strategy:,header,attr,delim:,quote:,tab,newline:", SerializeOpts.getOptionDefs()); opts.parse(args); setSerializeOpts(opts); bHeader = opts.hasOpt("header"); bAttr = opts.hasOpt("attr"); String delim = opts.getOptString("delim", ","); String quote = opts.getOptString("quote", "\""); // -tab overrides -delim if(opts.hasOpt("tab")) delim = "\t"; mNamingStrategy = Util .getNamingStrategy(opts.getOptString("nameing-strategy", "simple")); OutputPort stdout = getStdout(); try (OutputStream os = stdout.asOutputStream(getSerializeOpts()); Writer w = new OutputStreamWriter(os, getSerializeOpts().getOutput_text_encoding()); CSVFormatter mFormatter = new CSVFormatter(w, delim.charAt(0), quote.charAt(0))) { Processor processor = Shell.getProcessor(); mCompiler = processor.newXQueryCompiler(); InputPort in = getStdin(); XdmNode context = in.asXdmNode(getSerializeOpts()); // List<XValue> xvargs = opts.getRemainingArgs(); if(bAttr) { mFieldXPath = "for $a in @* order by $a/name() return $a/string()"; mHeaderXPath = "for $a in @* order by $a/name() return $a/node-name()"; } XQueryExecutable expr = mCompiler.compile(mRowXpath); XQueryEvaluator eval = expr.load(); if(context != null) eval.setContextItem(context); mLogger.trace("compiling header xpath: {}", mHeaderXPath); XQueryExecutable headerExpr = mCompiler.compile(mHeaderXPath); XQueryEvaluator headerEval = headerExpr.load(); mLogger.trace("compiling field xpath: {}", mFieldXPath); XQueryExecutable fieldExpr = mCompiler.compile(mFieldXPath); XQueryEvaluator fieldEval = fieldExpr.load(); boolean bFirst = true; for(XdmItem row : eval) { if(bFirst && bHeader) { writeHeader(mFormatter, row, headerEval); bFirst = false; } writeLine(mFormatter, row, fieldEval, false); } } return 0; } private void writeLine(CSVFormatter mFormatter, XdmItem row, XQueryEvaluator eval, boolean bHeader) throws SaxonApiException, IOException { mLogger.entry(row, eval, bHeader); List<String> fields = new ArrayList<String>(); if(row != null) eval.setContextItem(row); for(XdmItem field : eval) { fields.add(bHeader ? mNamingStrategy.fromXmlName(fromSaxonName(field)) : field.toString()); } CSVRecord rec = new CSVRecord(fields); if(bHeader) mFormatter.writeHeader(rec); else mFormatter.writeRow(rec); } private QName fromSaxonName(XdmItem field) { mLogger.entry(field); if(field instanceof XdmNode) { net.sf.saxon.s9api.QName se = ((XdmNode) field).getNodeName(); return new QName( se.getNamespaceURI(), se.getLocalName(), se.getPrefix()); } else return new QName(field.getStringValue()); } private void writeHeader(CSVFormatter mFormatter, XdmItem row, XQueryEvaluator eval) throws SaxonApiException, IOException { mLogger.entry(row, eval); writeLine(mFormatter, row, eval, true); } } // // // Copyright (C) 2008-2014 David A. Lee. // // The contents of this file are subject to the "Simplified BSD License" (the // "License"); // you may not use this file except in compliance with the License. You may // obtain a copy of the // License at http://www.opensource.org/licenses/bsd-license.php // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. // See the License for the specific language governing rights and limitations // under the License. // // The Original Code is: all this file. // // The Initial Developer of the Original Code is David A. Lee // // Portions created by (your name) are Copyright (C) (your legal entity). All // Rights Reserved. // // Contributor(s): none. //