Skip to content

Instantly share code, notes, and snippets.

@dansmith65
Last active December 20, 2015 21:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dansmith65/6198674 to your computer and use it in GitHub Desktop.
Save dansmith65/6198674 to your computer and use it in GitHub Desktop.
ScriptMaster function, for use in a FileMaker plug-in.
// XPathParseWithNamespace ( someXML ; xpathQuery ; namespaceList )
// adapted from this code: http://www.java2s.com/Code/Java/XML/implementsNamespaceContext.htm
// and the prior XPath Parse function in ScriptMaster
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
XPath xpath = XPathFactory.newInstance().newXPath();
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance()
if(namespaceList != null) {
domFactory.setNamespaceAware(true)
SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
namespaceList.tokenize().each() {
int sep = it.indexOf('=')
def prefix = it.substring(0, sep)
def uri = it.substring(sep+1, it.length())
nsContext.addNamespace(prefix, uri)
}
xpath.setNamespaceContext(nsContext);
}
DocumentBuilder builder = domFactory.newDocumentBuilder()
InputStream inputStream = new ByteArrayInputStream( someXML.getBytes("utf-8") );
Element records = builder.parse(inputStream).getDocumentElement();
def result
try
{
NodeList nodes = (NodeList)xpath.evaluate( xpathQuery, records, XPathConstants.NODESET );
def nodesAsString = nodes.collect { it.getTextContent() };
if (nodesAsString) {
result = nodesAsString.join("\r")
}
}
catch (XPathExpressionException e)
{
// this exception can occur when a function is used in xpath
result = xpath.evaluate( xpathQuery, records, XPathConstants.STRING );
}
return result
// end of procedural code //////////////////////////////////////////////////
class SimpleNamespaceContext implements NamespaceContext {
private Map<String, String> urisByPrefix = new HashMap<String, String>();
private Map<String, Set> prefixesByURI = new HashMap<String, Set>();
public SimpleNamespaceContext() {
addNamespace(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI);
addNamespace(XMLConstants.XMLNS_ATTRIBUTE, XMLConstants.XMLNS_ATTRIBUTE_NS_URI);
}
public synchronized void addNamespace(String prefix, String namespaceURI) {
urisByPrefix.put(prefix, namespaceURI);
if (prefixesByURI.containsKey(namespaceURI)) {
(prefixesByURI.get(namespaceURI)).add(prefix);
} else {
Set<String> set = new HashSet<String>();
set.add(prefix);
prefixesByURI.put(namespaceURI, set);
}
}
public String getNamespaceURI(String prefix) {
if (prefix == null)
throw new IllegalArgumentException("prefix cannot be null");
if (urisByPrefix.containsKey(prefix))
return (String) urisByPrefix.get(prefix);
else
return XMLConstants.NULL_NS_URI;
}
public String getPrefix(String namespaceURI) {
return (String) getPrefixes(namespaceURI).next();
}
public Iterator getPrefixes(String namespaceURI) {
if (namespaceURI == null)
throw new IllegalArgumentException("namespaceURI cannot be null");
if (prefixesByURI.containsKey(namespaceURI)) {
return ((Set) prefixesByURI.get(namespaceURI)).iterator();
} else {
return Collections.EMPTY_SET.iterator();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment