
com.centurylink.mdw.xml.XmlPath Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mdw-common Show documentation
Show all versions of mdw-common Show documentation
MDW is a microservices based workflow framework
/*
* Copyright (C) 2017 CenturyLink, Inc.
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.centurylink.mdw.xml;
//import java.util.HashMap;
//import java.util.Map;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlCursor.XmlBookmark;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/**
*
* XmlPath
*
* This class wraps around name-space agnostic XPath
*
* @version 1.0
*/
public class XmlPath {
private String path_string; // for parsing
private int n; // for parsing - string length of path_string
private int k; // for parsing - next char position;
private PathSegment path_seg; // result of parsing
public XmlPath(String path_string) throws XmlException {
this.path_string = path_string;
n = path_string.length();
k = 0;
Token token = getNextToken();
if (token!=null && token.kind==TokenKind.SLASH) token = getNextToken(); // ignore initial slash
path_seg = parse_path_segment(token);
}
/**
* Using XPath or XQuery.
* NOTE!!!! To use this code, need to include
* xbean_xpath.jar, saxon9.jar, saxon9-dom.jar in CLASSPATH
* in startWebLogic.cmd
* @param xmlbean
* @param path
* @return
*/
public static String evaluate(XmlObject xmlbean, String path) {
XmlCursor cursor = xmlbean.newCursor();
String value;
// 1.2.3. use XQuery or selectPath
//
// cursor.toFirstChild();
// String defaultNamespace = cursor.namespaceForPrefix("");
// String namespaceDecl = "declare default element namespace '" + defaultNamespace + "';";
// Map namespaces = new HashMap();
// cursor.getAllNamespaces(namespaces);
// for (String prefix : namespaces.keySet())
// {
// namespaceDecl += "declare namespace " + prefix + "='" + namespaces.get(prefix) + "';";
// }
// 1. use XQuery
// XmlCursor results = cursor.execQuery(namespaceDecl + path);
// value = (results==null)?null:results.getTextValue();
// 2. use selectPath on XmlObject
// XmlObject[] result = xmlbean.selectPath(namespaceDecl + path);
// 3. use selectPath on XmlCursor
// cursor.toParent();
// XmlOptions options = new XmlOptions();
// options.put(Path.PATH_DELEGATE_INTERFACE,"org.apache.xmlbeans.impl.xpath.saxon.XBeansXPath");
// cursor.selectPath(namespaceDecl + path, options);
// if (cursor.getSelectionCount()>0) {
// cursor.toNextSelection();
// value = cursor.getTextValue();
// } else value = null;
// 4. use our own implementation
try {
XmlPath matcher = new XmlPath(path);
value = matcher.evaluate_segment(cursor, matcher.path_seg);
} catch (XmlException e) {
value = null; // xpath syntax error - treated as no match
}
cursor.dispose();
return value;
}
public String getHashBucket() {
return path_seg.name==null?"*":path_seg.name; // either a root element name or *
}
public static String getRootNodeName(Document reqdoc) {
Node node = reqdoc.getFirstChild();
while (node!=null && node.getNodeType()!=Node.ELEMENT_NODE) {
node = node.getNextSibling();
}
return node==null?null:node.getNodeName();
}
public static String getRootNodeName(XmlObject xmlbean) {
XmlCursor cursor = xmlbean.newCursor();
cursor.toFirstChild();
return cursor.getName().getLocalPart();
}
public static String getRootNodeValue(XmlObject xmlbean) {
XmlCursor cursor = xmlbean.newCursor();
cursor.toFirstChild();
return cursor.getTextValue();
}
////// our own implementation of namespace-agnostic XPath matcher
private static class Condition {
String name;
boolean isAttribute;
String value;
}
private static class PathSegment {
String name; // special case: "*" - wild card; null - recursive descent
Condition condition;
PathSegment rest;
boolean isAttribute;
}
enum TokenKind { NAME, AT, VALUE, EQ, LBRACKET, RBRACKET, SLASH, STAR };
private static class Token {
TokenKind kind;
int start, end;
}
public String evaluate(XmlObject xmlbean) {
XmlCursor cursor = xmlbean.newCursor();
String value = evaluate_segment(cursor, path_seg);
cursor.dispose();
return value;
}
private static boolean isNameChar(char ch) {
return ch==':' || ch=='-' || ch=='_' || Character.isLetterOrDigit(ch);
}
private Token getNextToken() throws XmlException {
while (k=n) return null;
char ch = path_string.charAt(k);
Token token = new Token();
token.start = k;
token.end = k+1;
switch (ch) {
case '[': token.kind = TokenKind.LBRACKET; break;
case ']': token.kind = TokenKind.RBRACKET; break;
case '@': token.kind = TokenKind.AT; break;
case '=': token.kind = TokenKind.EQ; break;
case '*': token.kind = TokenKind.STAR; break;
case '/': token.kind = TokenKind.SLASH; break;
case '\'': token.kind = TokenKind.VALUE; getValueToken(token,'\''); break;
case '"': token.kind = TokenKind.VALUE; getValueToken(token,'"'); break;
default:
if (isNameChar(ch)) {
token.kind = TokenKind.NAME;
getNameToken(token);
} else {
throw new XmlException("Invalid XPath Pattern: " + path_string);
}
break;
}
k = token.end;
return token;
}
private void getNameToken(Token token) {
int l = k+1;
while (l
© 2015 - 2025 Weber Informatics LLC | Privacy Policy