|
From: <pm_...@us...> - 2012-02-07 08:51:47
|
Revision: 4519
http://mxquery.svn.sourceforge.net/mxquery/?rev=4519&view=rev
Author: pm_fischer
Date: 2012-02-07 08:51:38 +0000 (Tue, 07 Feb 2012)
Log Message:
-----------
Single path works for keep/keep sub
Modified Paths:
--------------
trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java
Modified: trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java 2012-02-07 08:50:27 UTC (rev 4518)
+++ trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java 2012-02-07 08:51:38 UTC (rev 4519)
@@ -34,8 +34,10 @@
import ch.ethz.mxquery.datamodel.xdm.TextToken;
import ch.ethz.mxquery.datamodel.xdm.Token;
import ch.ethz.mxquery.datamodel.xdm.TokenInterface;
+import ch.ethz.mxquery.exceptions.ErrorCodes;
import ch.ethz.mxquery.exceptions.MXQueryException;
import ch.ethz.mxquery.exceptions.QueryLocation;
+import ch.ethz.mxquery.model.AbstractStep;
import ch.ethz.mxquery.model.XDMIterator;
import ch.ethz.mxquery.util.Utils;
@@ -48,8 +50,8 @@
private int [] projPathPos;
+ int skipKeepLevel = -1;
-
private int PROJ_MODE_NORMAL = 0;
private int PROJ_MODE_SKIP = 1;
private int PROJ_MODE_KEEP_SUB = 2;
@@ -69,6 +71,7 @@
if (endOfSeq)
return tok;
try {
+ while (reader.hasNext()) {
int event = reader.getEventType();
switch (event) {
case XMLStreamConstants.ATTRIBUTE:
@@ -79,6 +82,11 @@
case XMLStreamConstants.CHARACTERS:
case XMLStreamConstants.SPACE:
{
+ if (curProjMode == PROJ_MODE_SKIP) {
+ reader.next();
+ continue;
+ }
+
StringBuffer mergedText = new StringBuffer();
while (event == XMLStreamConstants.CDATA || event == XMLStreamConstants.SPACE || event == XMLStreamConstants.CHARACTERS) {
mergedText.append(reader.getText());
@@ -88,6 +96,9 @@
return new TextToken(Type.TEXT_NODE_UNTYPED_ATOMIC, createNextTokenId(Type.TEXT_NODE_UNTYPED_ATOMIC, null), mergedText.toString(),curNsScope);
}
case XMLStreamConstants.COMMENT:
+ if (curProjMode == PROJ_MODE_SKIP)
+ continue;
+
tok = new CommentToken(createNextTokenId(Type.COMMENT, null), reader.getText(),curNsScope);
break;
case XMLStreamConstants.END_DOCUMENT:
@@ -99,10 +110,48 @@
String prefix = reader.getPrefix();
if (prefix != null && prefix.length() == 0)
prefix = null;
- XQName tName = new QName(ns_uri, prefix, name);
- tok = new ElementToken(Type.END_TAG, null, tName, curNsScope);
- checkCloseNsScope();
+ //
+ boolean stillSkip = false;
+ if (curProjMode == PROJ_MODE_SKIP && level == skipKeepLevel) {
+ curProjMode = PROJ_MODE_KEEP;
+ skipKeepLevel = -1;
+ stillSkip = true;
+ }
+ if (curProjMode == PROJ_MODE_KEEP && projPathPos[0] > 0) {
+ XQName curPathCheck = ((AbstractStep) ((Vector)projectionPaths.get(0)).elementAt(projPathPos[0])).getNodeTest().getXQName();
+ if (curPathCheck.getLocalPart().equals(name)) { //TODO: Handle namespaces
+ projPathPos[0]--;
+ }
+ if (projPathPos[0]+2 >= ((Vector)projectionPaths.get(0)).size())
+ stillSkip = false;
+ }
+
+ if (curProjMode == PROJ_MODE_MOVE && projPathPos[0] > 0) {
+ XQName curPathCheck = ((AbstractStep) ((Vector)projectionPaths.get(0)).elementAt(projPathPos[0]-1)).getNodeTest().getXQName();
+ if (curPathCheck.getLocalPart().equals(name)) { //TODO: Handle namespaces
+ projPathPos[0]--;
+ }
+ }
+
+ if (curProjMode == PROJ_MODE_KEEP_SUB && level == skipKeepLevel-1) {
+ XQName curPathCheck = ((AbstractStep) ((Vector)projectionPaths.get(0)).elementAt(projPathPos[0]-1)).getNodeTest().getXQName();
+ if (!curPathCheck.getLocalPart().equals(name))
+ throw new MXQueryException(ErrorCodes.A0007_EC_IO, "Inconsistency in projecting, expected "+curPathCheck.getLocalPart()+" saw "+name, loc);
+ curProjMode = PROJ_MODE_MOVE;
+ skipKeepLevel = -1;
+ projPathPos[0]-=2; // go back from the "keep" pseudo node
+ }
+ if (curProjMode != PROJ_MODE_SKIP && !stillSkip) {
+ XQName tName = new QName(ns_uri, prefix, name);
+ tok = new ElementToken(Type.END_TAG, null, tName, curNsScope);
+ checkCloseNsScope();
+ stillSkip = false;
+ }
level--;
+ if (curProjMode == PROJ_MODE_SKIP || stillSkip) {
+ reader.next();
+ continue;
+ }
break;
case XMLStreamConstants.ENTITY_DECLARATION: // not used
break;
@@ -111,17 +160,32 @@
case XMLStreamConstants.NAMESPACE:
break;
case XMLStreamConstants.NOTATION_DECLARATION:
+ if (curProjMode == PROJ_MODE_SKIP)
+ continue;
tok = new TextToken(createNextTokenId(Type.NOTATION, null), reader.getText());
break;
case XMLStreamConstants.PROCESSING_INSTRUCTION:
+ if (curProjMode == PROJ_MODE_SKIP)
+ continue;
tok = new ProcessingInstrToken(createNextTokenId(Type.PROCESSING_INSTRUCTION, null), reader.getPIData(), reader.getPITarget(),curNsScope);
break;
case XMLStreamConstants.START_DOCUMENT:
+ AbstractStep as = ((AbstractStep) ((Vector)projectionPaths.get(0)).elementAt(projPathPos[0]));
+ if (as == AbstractStep.ROOT_STEP) {
+ projPathPos[0]++;
+ curProjMode = PROJ_MODE_MOVE;
+ }
+
tok = new Token(Type.START_DOCUMENT,createNextTokenId(Type.START_DOCUMENT, null),curNsScope);
break;
case XMLStreamConstants.START_ELEMENT:
level++;
+ if (curProjMode == PROJ_MODE_SKIP) {
+ reader.next();
+ continue;
+ }
+
boolean foundId = false;
boolean foundIdREFS = false;
@@ -136,11 +200,37 @@
// projection:
// check if node name fits with currently active paths
-
-
+ boolean skipOnNext = false;
+ as = ((AbstractStep) ((Vector)projectionPaths.get(0)).elementAt(projPathPos[0]));
+ if (as == AbstractStep.KEEP_SUBTREE) {
+ curProjMode = PROJ_MODE_KEEP_SUB;
+ skipKeepLevel = level;
+ }
+ else {
+ XQName curPathCheck = as.getNodeTest().getXQName();
+ if (curPathCheck.getLocalPart().equals(name)) { //TODO: Handle namespaces
+ if (((Vector)projectionPaths.get(0)).size() <= projPathPos[0]+1) {
+ curProjMode = PROJ_MODE_SKIP;
+ skipOnNext = true;
+ skipKeepLevel = level;
+ }
+ else {
+ projPathPos[0]++;
+ curProjMode = PROJ_MODE_MOVE;
+ }
+
+ } else {
+ curProjMode = PROJ_MODE_SKIP;
+ skipKeepLevel = level;
+ }
+ }
+ if (curProjMode == PROJ_MODE_SKIP && !skipOnNext) {
+ reader.next();
+ continue;
+ }
if (prefix != null && prefix.length() == 0)
prefix = null;
- tName = new QName(ns_uri, prefix, name);
+ XQName tName = new QName(ns_uri, prefix, name);
tok = new ElementToken(Type.START_TAG, createNextTokenId(Type.START_TAG, tName.toString()), tName, curNsScope);
for (int i = 0; i < reader.getNamespaceCount(); i++) {
@@ -212,6 +302,9 @@
break;
default:
}
+ if (tok != null)
+ break;
+ }
if (reader.hasNext())
reader.next();
else {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <pm_...@us...> - 2012-02-07 08:55:16
|
Revision: 4521
http://mxquery.svn.sourceforge.net/mxquery/?rev=4521&view=rev
Author: pm_fischer
Date: 2012-02-07 08:55:10 +0000 (Tue, 07 Feb 2012)
Log Message:
-----------
Namespace support for projection
Modified Paths:
--------------
trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java
Modified: trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java 2012-02-07 08:53:50 UTC (rev 4520)
+++ trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java 2012-02-07 08:55:10 UTC (rev 4521)
@@ -83,8 +83,6 @@
private int [] projPathPos;
private Stack bufferedPathName;
- private Stack bufferedPathURI;
- private Stack bufferedPathPrefix;
private Stack bufferedAttributes;
private int pathProducedLevel = 0;
@@ -144,7 +142,7 @@
break;
case XMLStreamConstants.END_ELEMENT: {
boolean emitTag = false;
- String name_debug = reader.getLocalName();
+ javax.xml.namespace.QName name_debug = reader.getName();
switch (curProjMode) {
case PROJ_MODE_KEEP_SUB:
//KEEP_SUB->MOVE: reached skipKeepLevel
@@ -169,12 +167,12 @@
}
else
if (skipKeepLevel == level) {
- String name = reader.getLocalName();
+ javax.xml.namespace.QName name = reader.getName();
Vector path = (Vector)projectionPaths.get(0);
XQName curPathCheck = ((AbstractStep) (path).elementAt(projPathPos[0])).getNodeTest().getXQName();
- if (curPathCheck.getLocalPart().equals(name) || level != projPathPos[0]) {
+ if (equalsQNames(curPathCheck,name) || level != projPathPos[0]) {
curProjMode = PROJ_MODE_KEEP;
} else {
curProjMode = PROJ_MODE_MOVE;
@@ -188,10 +186,10 @@
}
break;
case PROJ_MODE_MOVE: {
- String name = reader.getLocalName();
+ javax.xml.namespace.QName name = reader.getName();
XQName curPathCheck = ((AbstractStep) ((Vector)projectionPaths.get(0)).elementAt(projPathPos[0]-1)).getNodeTest().getXQName();
- if (!curPathCheck.getLocalPart().equals(name))
- throw new MXQueryException(ErrorCodes.A0007_EC_IO, "Inconsistency in projecting, expected "+curPathCheck.getLocalPart()+" saw "+name, loc);
+ if (!equalsQNames(curPathCheck,name))
+ throw new MXQueryException(ErrorCodes.A0007_EC_IO, "Inconsistency in projecting, expected "+curPathCheck+" saw "+name, loc);
if (pathProducedLevel >= level) {
emitTag = true;
@@ -205,7 +203,7 @@
//decide if keep or move directly, when we came from SKIP
//SKIP->KEEP: reached skipKeepLevel, level above matched
// SKIP->MOVE: reached skipKeepLevel, level above did not match
- String name = reader.getLocalName();
+ javax.xml.namespace.QName name = reader.getName();
Vector path = (Vector)projectionPaths.get(0);
@@ -222,8 +220,8 @@
projPathPos[0]--;
}
XQName curPathCheck = ((AbstractStep) (path).elementAt(projPathPos[0])).getNodeTest().getXQName();
- if (!curPathCheck.getLocalPart().equals(name))
- throw new MXQueryException(ErrorCodes.A0007_EC_IO, "Inconsistency in projecting, expected "+curPathCheck.getLocalPart()+" saw "+name, loc);
+ if (!equalsQNames(curPathCheck,name))
+ throw new MXQueryException(ErrorCodes.A0007_EC_IO, "Inconsistency in projecting, expected "+curPathCheck+" saw "+name, loc);
//projPathPos[0]--;
curProjMode = PROJ_MODE_MOVE;
@@ -240,12 +238,8 @@
//
if (emitTag) {
- String name = reader.getLocalName();
- String ns_uri = reader.getNamespaceURI();
- String prefix = reader.getPrefix();
- if (prefix != null && prefix.length() == 0)
- prefix = null;
- XQName tName = new QName(ns_uri, prefix, name);
+ javax.xml.namespace.QName name = reader.getName();
+ XQName tName = transformQName(name);
tok = new ElementToken(Type.END_TAG, null, tName, curNsScope);
checkCloseNsScope();
level--;
@@ -297,11 +291,11 @@
String [] xmlIdREFS = null;
boolean createdNSScope = false;
- String name = reader.getLocalName();
- String ns_uri = reader.getNamespaceURI();
- String prefix = reader.getPrefix();
- if (prefix != null && prefix.length() == 0)
- prefix = null;
+ javax.xml.namespace.QName name = reader.getName();
+// String ns_uri = reader.getNamespaceURI();
+// String prefix = reader.getPrefix();
+// if (prefix != null && prefix.length() == 0)
+// prefix = null;
// projection:
@@ -321,22 +315,16 @@
emitTag = true;
} else {
XQName curPathCheck = as.getNodeTest().getXQName();
- if (curPathCheck.getLocalPart().equals(name)) { //TODO: Handle namespaces
+ if (equalsQNames(curPathCheck,name)) {
// check name: if true, then either keep or move
Vector path = ((Vector)projectionPaths.get(0));
if (path.size() <= projPathPos[0]+1) {
- tok = extractPendingElements(
- name,
- ns_uri,
- prefix);
+ tok = extractPendingElements(name);
curProjMode = PROJ_MODE_KEEP;
skipKeepLevel = level+1;
}
else if (path.elementAt(path.size()-1)==AbstractStep.KEEP_SUBTREE && path.size() <= projPathPos[0]+2) {
- tok = extractPendingElements(
- name,
- ns_uri,
- prefix);
+ tok = extractPendingElements(name);
curProjMode = PROJ_MODE_KEEP_SUB;
skipKeepLevel = level;
}
@@ -368,9 +356,9 @@
continue;
}
if (emitTag) {
- if (prefix != null && prefix.length() == 0)
- prefix = null;
- XQName tName = new QName(ns_uri, prefix, name);
+// if (prefix != null && prefix.length() == 0)
+// prefix = null;
+ XQName tName = transformQName(name);
tok = new ElementToken(Type.START_TAG, createNextTokenId(Type.START_TAG, tName.toString()), tName, curNsScope);
}
if (curProjMode == PROJ_MODE_KEEP)
@@ -469,15 +457,14 @@
return Token.END_SEQUENCE_TOKEN;
}
- private TokenInterface extractPendingElements(String name, String ns_uri,
- String prefix) {
+ private TokenInterface extractPendingElements(javax.xml.namespace.QName qn) {
// we have reached the end of the path, and no subtree is needed: KEEP
// emit all the pending element nodes
for (int i=pathProducedLevel; i<bufferedPathName.size();i++) {
- XQName tName = new QName(null, null, (String)bufferedPathName.elementAt(i));
+ XQName tName = transformQName((javax.xml.namespace.QName)bufferedPathName.elementAt(i));
tokensList.add(new ElementToken(Type.START_TAG, createNextTokenId(Type.START_TAG, tName.toString()), tName, curNsScope));
}
- XQName tName = new QName(ns_uri, prefix, name);
+ XQName tName = transformQName(qn);
tokensList.add(new ElementToken(Type.START_TAG, createNextTokenId(Type.START_TAG, tName.toString()), tName, curNsScope));
pathProducedLevel = level;
return (TokenInterface)tokensList.removeFirst();
@@ -506,4 +493,26 @@
for (int i=0;i<projPathPos.length;i++)
projPathPos[i] = 0;
}
+
+ QName transformQName(javax.xml.namespace.QName qn) {
+ //TODO: We might create a pool/cache of QNames
+ String prefix = qn.getPrefix();
+ if (prefix != null && prefix.length() == 0)
+ prefix = null;
+ return new QName(qn.getNamespaceURI(),prefix,qn.getLocalPart());
+ }
+
+ boolean equalsQNames(XQName mxqQName, javax.xml.namespace.QName jQName) {
+ if (!mxqQName.getLocalPart().equals(jQName.getLocalPart()))
+ return false;
+ if (mxqQName.getNamespaceURI()==null) {
+ if (!jQName.getNamespaceURI().equals(javax.xml.XMLConstants.NULL_NS_URI))
+ return false;
+ else return true;
+ }
+ if (!mxqQName.getNamespaceURI().equals(jQName.getNamespaceURI()))
+ return false;
+ return true;
+ }
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <pm_...@us...> - 2012-02-07 08:56:28
|
Revision: 4522
http://mxquery.svn.sourceforge.net/mxquery/?rev=4522&view=rev
Author: pm_fischer
Date: 2012-02-07 08:56:21 +0000 (Tue, 07 Feb 2012)
Log Message:
-----------
Introduced code to handle multiple paths, working for a single path
Modified Paths:
--------------
trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java
Modified: trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java 2012-02-07 08:55:10 UTC (rev 4521)
+++ trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java 2012-02-07 08:56:21 UTC (rev 4522)
@@ -24,7 +24,7 @@
*
* We keep track of the level on which we switched to SKIP/SUB_KEEP: top skip, top keep node => skipKeepLevel
*
- * Transitions:
+ * Transitions (on a single path):
*
* Driven by opening tags
* MOVE->KEEP: We reach the end of a projection path, match the name and do not keep descendants => produce
@@ -42,7 +42,39 @@
* KEEP_SUB->MOVE: reached skipKeepLevel
* MOVE->MOVE: on a projection path, match name close
* SKIP->SKIP: any closing tag greater than skipKeepLevel
- * KEEP_SUB->KEEP_SUB: any closing tag greater than skipKeepLevel
+ * KEEP_SUB->KEEP_SUB: any closing tag greater than skipKeepLevel
+ *
+ * Handling multiple projection paths:
+ * For each path, we record
+ * - the step that should be considered, creating the active suffix: projPathPos
+ *
+ * In general, we keep track of
+ * - the set of currently active paths: activePaths
+ * - the last step on which an in-active path was active: lastActiveStep
+ * - the "stack" of kept nodes: keptNodes -> pointers to seen opening nodes
+ *
+ * active/inactive tracking:
+ * - all paths start off active
+ * when opening an element, check if name matches
+ * if not, remove from set of active paths, set lastActiveLevel to current level
+ * when closing an element, go through the non-active paths and check if one of them is at lastActiveLevel. If yes, add back to active paths
+ *
+ * active paths vs modes:
+ * opening:
+ * if any active path goes to KEEP_SUB, go to KEEP_SUB. Ignore all the suffixes until the output has been produced,
+ * if no paths are active any more, go to SKIP
+ * if a path goes to KEEP: if other paths are active/MOVE, add to the set of kept paths (as these path might not produce). Otherwise, go to KEEP, emit
+ * otherwise, stay in MOVE
+ *
+ * if emit, produce path to this point, set produced level and clean up kept nodes
+ *
+ * closing:
+ * KEEP_SUB -> KEEP_SUB, SKIP->SKIP: as before
+ * KEEP_SUB: -> MOVE, all info should be fine
+ * SKIP-> MOVE/KEEP:
+ * MOVE-> MOVE: add previously closed paths to active if lastLevel is OK
+ * check
+ *
*/
package ch.ethz.mxquery.xdmio.xmlAdapters;
@@ -50,18 +82,20 @@
import java.util.LinkedList;
import java.util.Vector;
import java.util.Stack;
+import java.util.HashSet;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
+import sun.dc.pr.PathStroker;
+
import ch.ethz.mxquery.contextConfig.Context;
import ch.ethz.mxquery.datamodel.QName;
import ch.ethz.mxquery.datamodel.XQName;
import ch.ethz.mxquery.datamodel.types.Type;
import ch.ethz.mxquery.datamodel.xdm.CommentToken;
import ch.ethz.mxquery.datamodel.xdm.ElementToken;
-import ch.ethz.mxquery.datamodel.xdm.NamedToken;
import ch.ethz.mxquery.datamodel.xdm.ProcessingInstrToken;
import ch.ethz.mxquery.datamodel.xdm.TextToken;
import ch.ethz.mxquery.datamodel.xdm.Token;
@@ -85,6 +119,11 @@
private Stack bufferedPathName;
private Stack bufferedAttributes;
+ private HashSet activePaths;
+ private int [] lastActiveStep;
+
+ private Stack keptNodes; // level?, pointer to bufferPathName
+
private int pathProducedLevel = 0;
int skipKeepLevel = -1;
@@ -112,7 +151,7 @@
int event = reader.getEventType();
switch (event) {
case XMLStreamConstants.ATTRIBUTE:
- break;
+ break;
case XMLStreamConstants.DTD:
break;
case XMLStreamConstants.CDATA:
@@ -150,6 +189,7 @@
if (skipKeepLevel == level) {
curProjMode = PROJ_MODE_MOVE;
skipKeepLevel = -1;
+ bufferedPathName.pop();
pathProducedLevel--;
}
emitTag = true;
@@ -158,6 +198,7 @@
// go to "KEEP", check later if we keep or move
if (skipKeepLevel == level+1) {
+ restoreDroppedPaths();
curProjMode = PROJ_MODE_MOVE;
if (pathProducedLevel >= level) {
emitTag = true;
@@ -168,15 +209,31 @@
else
if (skipKeepLevel == level) {
javax.xml.namespace.QName name = reader.getName();
+ boolean foundKeep = false;
+ for (int pathPos=0;pathPos<projectionPaths.size();pathPos++) {
+ // check those paths that we active before we started skipping
+ // last state was MOVE
+ if (lastActiveStep[pathPos]==level) {
+ // they will become active again
+ activePaths.add(new Integer(pathPos));
+ }
+ // last step was KEEP
+ if (lastActiveStep[pathPos]+1==level) {
+ // they will become active again
+ activePaths.add(new Integer(pathPos));
+ // decide if we go to KEEP
+ Vector path = (Vector)projectionPaths.get(pathPos);
+ XQName curPathCheck = ((AbstractStep) (path).elementAt(projPathPos[pathPos])).getNodeTest().getXQName();
+ if (equalsQNames(curPathCheck,name) || /*FIXME*/ level != projPathPos[pathPos]) {
+ foundKeep = true;
+ }
+ }
+ }
+ if (foundKeep)
+ curProjMode = PROJ_MODE_KEEP;
+ else
+ curProjMode = PROJ_MODE_MOVE;
- Vector path = (Vector)projectionPaths.get(0);
-
- XQName curPathCheck = ((AbstractStep) (path).elementAt(projPathPos[0])).getNodeTest().getXQName();
- if (equalsQNames(curPathCheck,name) || level != projPathPos[0]) {
- curProjMode = PROJ_MODE_KEEP;
- } else {
- curProjMode = PROJ_MODE_MOVE;
- }
skipKeepLevel = -1;
}
else {
@@ -186,11 +243,20 @@
}
break;
case PROJ_MODE_MOVE: {
- javax.xml.namespace.QName name = reader.getName();
+ restoreDroppedPaths();
+ javax.xml.namespace.QName name = reader.getName();
+ //TODO: remove this consistency check - only trivially possible for a single path
XQName curPathCheck = ((AbstractStep) ((Vector)projectionPaths.get(0)).elementAt(projPathPos[0]-1)).getNodeTest().getXQName();
if (!equalsQNames(curPathCheck,name))
throw new MXQueryException(ErrorCodes.A0007_EC_IO, "Inconsistency in projecting, expected "+curPathCheck+" saw "+name, loc);
-
+
+ // if kept nodes are on the path, i.e. we had "KEEP" for them but did not produce any lower
+ // output them
+ if (!keptNodes.empty()&&((Integer)keptNodes.peek()).intValue() == level ) {
+ tok = extractPendingElements();
+ // TODO: extract+emit!
+ }
+
if (pathProducedLevel >= level) {
emitTag = true;
pathProducedLevel--;
@@ -199,29 +265,29 @@
bufferedPathName.pop();
} break;
case PROJ_MODE_KEEP: {
-
+ bufferedPathName.pop();
//decide if keep or move directly, when we came from SKIP
//SKIP->KEEP: reached skipKeepLevel, level above matched
// SKIP->MOVE: reached skipKeepLevel, level above did not match
javax.xml.namespace.QName name = reader.getName();
- Vector path = (Vector)projectionPaths.get(0);
+// Vector path = (Vector)projectionPaths.get(0);
- if (path.size() == projPathPos[0]+1) {// last element in path, and not a "KEEP"
+// if (path.size() == projPathPos[0]+1) {// last element in path, and not a "KEEP"
// really keep
emitTag = true;
- } else {
- curProjMode = PROJ_MODE_MOVE;
- if (bufferedPathName.size() > level && bufferedPathName.get(level).equals(name)) {
- emitTag = true;
-
- }
- bufferedPathName.pop();
- projPathPos[0]--;
- }
- XQName curPathCheck = ((AbstractStep) (path).elementAt(projPathPos[0])).getNodeTest().getXQName();
- if (!equalsQNames(curPathCheck,name))
- throw new MXQueryException(ErrorCodes.A0007_EC_IO, "Inconsistency in projecting, expected "+curPathCheck+" saw "+name, loc);
+// } else {
+// curProjMode = PROJ_MODE_MOVE;
+// if (bufferedPathName.size() > level && bufferedPathName.get(level).equals(name)) {
+// emitTag = true;
+//
+// }
+// bufferedPathName.pop();
+// projPathPos[0]--;
+// }
+// XQName curPathCheck = ((AbstractStep) (path).elementAt(projPathPos[0])).getNodeTest().getXQName();
+// if (!equalsQNames(curPathCheck,name))
+// throw new MXQueryException(ErrorCodes.A0007_EC_IO, "Inconsistency in projecting, expected "+curPathCheck+" saw "+name, loc);
//projPathPos[0]--;
curProjMode = PROJ_MODE_MOVE;
@@ -292,57 +358,64 @@
boolean createdNSScope = false;
javax.xml.namespace.QName name = reader.getName();
-// String ns_uri = reader.getNamespaceURI();
-// String prefix = reader.getPrefix();
-// if (prefix != null && prefix.length() == 0)
-// prefix = null;
// projection:
boolean emitTag = false;
+ int oldMode = curProjMode;
+ boolean keepNode = false;
+
// check if node name fits with currently active paths
switch (curProjMode) {
- case PROJ_MODE_KEEP_SUB:
- emitTag = true; // no check, just output
- break;
+ case PROJ_MODE_MOVE:
+ boolean bufferNode = false;
- case PROJ_MODE_MOVE:
- as = ((AbstractStep) ((Vector)projectionPaths.get(0)).elementAt(projPathPos[0]));
+ java.util.Iterator pathIt = activePaths.iterator();
+ while (pathIt.hasNext()) {
+ int pathPos = ((Integer)pathIt.next()).intValue();
+ as = ((AbstractStep) ((Vector)projectionPaths.get(pathPos)).elementAt(projPathPos[pathPos]));
+ // if any path goes to keep, we need to keep everything below
if (as == AbstractStep.KEEP_SUBTREE) {
curProjMode = PROJ_MODE_KEEP_SUB;
skipKeepLevel = level;
emitTag = true;
+ // no need to cover individual paths any more?
+ // break?
} else {
XQName curPathCheck = as.getNodeTest().getXQName();
- if (equalsQNames(curPathCheck,name)) {
+ if (equalsQNames(curPathCheck,name)) {
+ // possibly relevant path, so buffer the path
+ bufferNode = true;
// check name: if true, then either keep or move
- Vector path = ((Vector)projectionPaths.get(0));
- if (path.size() <= projPathPos[0]+1) {
- tok = extractPendingElements(name);
- curProjMode = PROJ_MODE_KEEP;
- skipKeepLevel = level+1;
+ Vector path = ((Vector)projectionPaths.get(pathPos));
+ if (path.size() <= projPathPos[pathPos]+1) {
+ //curProjMode = PROJ_MODE_KEEP;
+ // mark that we may have to keep this node
+ keepNode = true;
+ lastActiveStep[pathPos] = level;
+ activePaths.remove(new Integer(pathPos));
}
- else if (path.elementAt(path.size()-1)==AbstractStep.KEEP_SUBTREE && path.size() <= projPathPos[0]+2) {
- tok = extractPendingElements(name);
+ else if (path.elementAt(path.size()-1)==AbstractStep.KEEP_SUBTREE && path.size() <= projPathPos[pathPos]+2) {
curProjMode = PROJ_MODE_KEEP_SUB;
- skipKeepLevel = level;
}
- else {
- projPathPos[0]++;
- curProjMode = PROJ_MODE_MOVE;
- bufferedPathName.push(name);
- reader.next();
- continue; //buffer contents until we find a projection result
- }
+ // else stay in MOVE
- } else { // otherwise go to skip
- skipKeepLevel = level;
- curProjMode = PROJ_MODE_SKIP;
+ } else { // otherwise remove from set of active paths
+ lastActiveStep[pathPos] = level;
+ activePaths.remove(new Integer(pathPos));
+ //curProjMode = PROJ_MODE_SKIP;
}
}
-
+ }
+ if (bufferNode)
+ bufferedPathName.push(name);
+
break;
+ case PROJ_MODE_KEEP_SUB:
+ emitTag = true; // no check, just output
+ break;
+
case PROJ_MODE_KEEP: {
//emitTag = true;
skipKeepLevel = level;
@@ -351,6 +424,53 @@
break;
// we handled SKIP already above
}
+
+ // Global Check
+ // determine new mode by checking old state, active nodes etc
+ // MOVE, activePaths empty => SKIP
+
+ if (curProjMode==PROJ_MODE_MOVE && activePaths.isEmpty()) {
+ if (!keepNode)
+ curProjMode = PROJ_MODE_SKIP;
+ else
+ curProjMode = PROJ_MODE_KEEP;
+ skipKeepLevel = level;
+ }
+
+
+ // TODO: set up/sort things out according to state transitions
+
+ if (oldMode == PROJ_MODE_MOVE && curProjMode == PROJ_MODE_MOVE) {
+ // advance all active paths
+ java.util.Iterator pathIt = activePaths.iterator();
+ while (pathIt.hasNext()) {
+ int pathPos = ((Integer)pathIt.next()).intValue();
+
+ projPathPos[pathPos]++;
+ }
+ if (keepNode)
+ // put this node on the "keep" list
+ // if we move on
+ keptNodes.push(new Integer(level));
+ reader.next();
+ continue; //buffer contents until we find a projection result
+ }
+
+ if (oldMode == PROJ_MODE_MOVE && (curProjMode == PROJ_MODE_KEEP || curProjMode == PROJ_MODE_KEEP_SUB)) {
+ // once we found a element to keep, push out the pending ones
+ tok = extractPendingElements();
+
+ // for keep, we will skip (and resume) below
+ if (curProjMode == PROJ_MODE_KEEP) {
+ skipKeepLevel = level+1;
+ }
+ else // keep_sub, we start here
+ skipKeepLevel = level;
+
+ }
+
+ oldMode = curProjMode;
+
if (curProjMode == PROJ_MODE_SKIP) {
reader.next();
continue;
@@ -457,16 +577,27 @@
return Token.END_SEQUENCE_TOKEN;
}
- private TokenInterface extractPendingElements(javax.xml.namespace.QName qn) {
+ private void restoreDroppedPaths() {
+ // add back paths that have become inactive
+ for (int pathPos = 0;pathPos<projectionPaths.size();pathPos++) {
+ if (lastActiveStep[pathPos] == level) {
+ activePaths.add(new Integer(pathPos));
+ lastActiveStep[pathPos] = -1;
+ }
+ //AbstractStep as = ((AbstractStep) ((Vector)projectionPaths.get(pathPos)).elementAt(projPathPos[pathPos]));
+ }
+ }
+
+ private TokenInterface extractPendingElements() {
// we have reached the end of the path, and no subtree is needed: KEEP
// emit all the pending element nodes
for (int i=pathProducedLevel; i<bufferedPathName.size();i++) {
XQName tName = transformQName((javax.xml.namespace.QName)bufferedPathName.elementAt(i));
tokensList.add(new ElementToken(Type.START_TAG, createNextTokenId(Type.START_TAG, tName.toString()), tName, curNsScope));
}
- XQName tName = transformQName(qn);
- tokensList.add(new ElementToken(Type.START_TAG, createNextTokenId(Type.START_TAG, tName.toString()), tName, curNsScope));
pathProducedLevel = level;
+ // clean up the kept nodes, as we now produce along the path on which they are
+ keptNodes.clear();
return (TokenInterface)tokensList.removeFirst();
}
@@ -490,8 +621,14 @@
projectionPaths = new ArrayList();
projectionPaths.addAll(paths);
projPathPos = new int[projectionPaths.size()];
- for (int i=0;i<projPathPos.length;i++)
+ activePaths = new HashSet();
+ lastActiveStep = new int[projectionPaths.size()];
+ for (int i=0;i<projPathPos.length;i++) {
projPathPos[i] = 0;
+ activePaths.add(new Integer(i));
+ lastActiveStep[i] = -1;
+ }
+ keptNodes = new Stack();
}
QName transformQName(javax.xml.namespace.QName qn) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <pm_...@us...> - 2012-02-07 08:57:41
|
Revision: 4523
http://mxquery.svn.sourceforge.net/mxquery/?rev=4523&view=rev
Author: pm_fischer
Date: 2012-02-07 08:57:31 +0000 (Tue, 07 Feb 2012)
Log Message:
-----------
more merging
Modified Paths:
--------------
trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java
Modified: trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java
===================================================================
--- trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java 2012-02-07 08:56:21 UTC (rev 4522)
+++ trunk/MXQuery/src/ch/ethz/mxquery/xdmio/xmlAdapters/NonValidatingStaxAdapterProjection.java 2012-02-07 08:57:31 UTC (rev 4523)
@@ -171,9 +171,10 @@
return new TextToken(Type.TEXT_NODE_UNTYPED_ATOMIC, createNextTokenId(Type.TEXT_NODE_UNTYPED_ATOMIC, null), mergedText.toString(),curNsScope);
}
case XMLStreamConstants.COMMENT:
- if (curProjMode == PROJ_MODE_SKIP || curProjMode == PROJ_MODE_MOVE)
+ if (curProjMode == PROJ_MODE_SKIP || curProjMode == PROJ_MODE_MOVE) {
+ reader.next();
continue;
-
+ }
tok = new CommentToken(createNextTokenId(Type.COMMENT, null), reader.getText(),curNsScope);
break;
case XMLStreamConstants.END_DOCUMENT:
@@ -181,16 +182,23 @@
break;
case XMLStreamConstants.END_ELEMENT: {
boolean emitTag = false;
- javax.xml.namespace.QName name_debug = reader.getName();
+ tok = null;
+ javax.xml.namespace.QName name = reader.getName();
switch (curProjMode) {
case PROJ_MODE_KEEP_SUB:
//KEEP_SUB->MOVE: reached skipKeepLevel
//KEEP_SUB->KEEP_SUB: any closing tag greater than skipKeepLevel
if (skipKeepLevel == level) {
+ restoreDroppedPaths();
curProjMode = PROJ_MODE_MOVE;
skipKeepLevel = -1;
bufferedPathName.pop();
pathProducedLevel--;
+// java.util.Iterator pathIt = activePaths.iterator();
+// while (pathIt.hasNext()) {
+// int pathPos = ((Integer)pathIt.next()).intValue();
+// projPathPos[pathPos]--;
+// }
}
emitTag = true;
break;
@@ -198,8 +206,10 @@
// go to "KEEP", check later if we keep or move
if (skipKeepLevel == level+1) {
+ //javax.xml.namespace.QName name = reader.getName();
+ curProjMode = PROJ_MODE_MOVE;
restoreDroppedPaths();
- curProjMode = PROJ_MODE_MOVE;
+
if (pathProducedLevel >= level) {
emitTag = true;
pathProducedLevel--;
@@ -208,7 +218,8 @@
}
else
if (skipKeepLevel == level) {
- javax.xml.namespace.QName name = reader.getName();
+ //javax.xml.namespace.QName name = reader.getName();
+ boolean foundMove = false;
boolean foundKeep = false;
for (int pathPos=0;pathPos<projectionPaths.size();pathPos++) {
// check those paths that we active before we started skipping
@@ -216,25 +227,24 @@
if (lastActiveStep[pathPos]==level) {
// they will become active again
activePaths.add(new Integer(pathPos));
+ foundMove =true;
}
- // last step was KEEP
- if (lastActiveStep[pathPos]+1==level) {
- // they will become active again
- activePaths.add(new Integer(pathPos));
- // decide if we go to KEEP
- Vector path = (Vector)projectionPaths.get(pathPos);
- XQName curPathCheck = ((AbstractStep) (path).elementAt(projPathPos[pathPos])).getNodeTest().getXQName();
- if (equalsQNames(curPathCheck,name) || /*FIXME*/ level != projPathPos[pathPos]) {
- foundKeep = true;
- }
+
+ Vector path = (Vector)projectionPaths.get(pathPos);
+ if (path.size()==level && lastActiveStep[pathPos]==level-1) {
+// activePaths.add(new Integer(pathPos));
+ foundKeep = true;
}
+
}
- if (foundKeep)
+ if (foundMove) {
+ curProjMode = PROJ_MODE_MOVE;
+ skipKeepLevel = -1;
+ } else
+ if (foundKeep) {
curProjMode = PROJ_MODE_KEEP;
- else
- curProjMode = PROJ_MODE_MOVE;
-
- skipKeepLevel = -1;
+ skipKeepLevel = -1;
+ }
}
else {
reader.next();
@@ -243,25 +253,33 @@
}
break;
case PROJ_MODE_MOVE: {
- restoreDroppedPaths();
- javax.xml.namespace.QName name = reader.getName();
+
+ //javax.xml.namespace.QName name = reader.getName();
//TODO: remove this consistency check - only trivially possible for a single path
- XQName curPathCheck = ((AbstractStep) ((Vector)projectionPaths.get(0)).elementAt(projPathPos[0]-1)).getNodeTest().getXQName();
- if (!equalsQNames(curPathCheck,name))
- throw new MXQueryException(ErrorCodes.A0007_EC_IO, "Inconsistency in projecting, expected "+curPathCheck+" saw "+name, loc);
+// XQName curPathCheck = ((AbstractStep) ((Vector)projectionPaths.get(0)).elementAt(projPathPos[0]-1)).getNodeTest().getXQName();
+// if (!equalsQNames(curPathCheck,name))
+// throw new MXQueryException(ErrorCodes.A0007_EC_IO, "Inconsistency in projecting, expected "+curPathCheck+" saw "+name, loc);
// if kept nodes are on the path, i.e. we had "KEEP" for them but did not produce any lower
// output them
if (!keptNodes.empty()&&((Integer)keptNodes.peek()).intValue() == level ) {
tok = extractPendingElements();
- // TODO: extract+emit!
- }
+ XQName tName = transformQName((javax.xml.namespace.QName)bufferedPathName.elementAt(level-1));
+ tokensList.add(new ElementToken(Type.END_TAG, createNextTokenId(Type.END_TAG, tName.toString()), tName, curNsScope));
+ pathProducedLevel--;
+ } else
if (pathProducedLevel >= level) {
emitTag = true;
pathProducedLevel--;
}
- projPathPos[0]--;
+ java.util.Iterator pathIt = activePaths.iterator();
+ while (pathIt.hasNext()) {
+ int pathPos = ((Integer)pathIt.next()).intValue();
+
+ projPathPos[pathPos]--;
+ }
+ restoreDroppedPaths();
bufferedPathName.pop();
} break;
case PROJ_MODE_KEEP: {
@@ -269,8 +287,18 @@
//decide if keep or move directly, when we came from SKIP
//SKIP->KEEP: reached skipKeepLevel, level above matched
// SKIP->MOVE: reached skipKeepLevel, level above did not match
- javax.xml.namespace.QName name = reader.getName();
-
+ //javax.xml.namespace.QName name = reader.getName();
+ for (int pathPos=0;pathPos<projectionPaths.size();pathPos++) {
+ Vector path = (Vector)projectionPaths.get(pathPos);
+
+ if (path.size()==level+1) {
+ XQName curPathCheck = ((AbstractStep) (path).elementAt(projPathPos[pathPos])).getNodeTest().getXQName();
+ if (equalsQNames(curPathCheck, name))
+ activePaths.add(new Integer(pathPos));
+ }
+
+ }
+
// Vector path = (Vector)projectionPaths.get(0);
// if (path.size() == projPathPos[0]+1) {// last element in path, and not a "KEEP"
@@ -303,15 +331,14 @@
//
+ level--;
if (emitTag) {
- javax.xml.namespace.QName name = reader.getName();
+ //javax.xml.namespace.QName name = reader.getName();
XQName tName = transformQName(name);
tok = new ElementToken(Type.END_TAG, null, tName, curNsScope);
checkCloseNsScope();
- level--;
- } else {
- reader.next();
- level--;
+ } else if (tok==null){
+ reader.next();
continue;
}
@@ -324,13 +351,17 @@
case XMLStreamConstants.NAMESPACE:
break;
case XMLStreamConstants.NOTATION_DECLARATION:
- if (curProjMode == PROJ_MODE_SKIP || curProjMode == PROJ_MODE_MOVE)
+ if (curProjMode == PROJ_MODE_SKIP || curProjMode == PROJ_MODE_MOVE) {
+ reader.next();
continue;
+ }
tok = new TextToken(createNextTokenId(Type.NOTATION, null), reader.getText());
break;
case XMLStreamConstants.PROCESSING_INSTRUCTION:
- if (curProjMode == PROJ_MODE_SKIP || curProjMode == PROJ_MODE_MOVE)
+ if (curProjMode == PROJ_MODE_SKIP || curProjMode == PROJ_MODE_MOVE) {
+ reader.next();
continue;
+ }
tok = new ProcessingInstrToken(createNextTokenId(Type.PROCESSING_INSTRUCTION, null), reader.getPIData(), reader.getPITarget(),curNsScope);
break;
case XMLStreamConstants.START_DOCUMENT:
@@ -402,7 +433,12 @@
// else stay in MOVE
} else { // otherwise remove from set of active paths
- lastActiveStep[pathPos] = level;
+ // only assign new last active
+// if (lastActiveStep[pathPos]<0)
+ lastActiveStep[pathPos] = level;
+// else {
+// lastActiveStep[pathPos] = lastActiveStep[pathPos]; // dummy for debugging
+// }
activePaths.remove(new Integer(pathPos));
//curProjMode = PROJ_MODE_SKIP;
}
@@ -560,6 +596,7 @@
reader.next();
else {
endOfSeq = true;
+ tok = Token.END_SEQUENCE_TOKEN;
}
return tok;
} catch (XMLStreamException e) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|