summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/util/XmlHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/openslx/util/XmlHelper.java')
-rw-r--r--src/main/java/org/openslx/util/XmlHelper.java115
1 files changed, 108 insertions, 7 deletions
diff --git a/src/main/java/org/openslx/util/XmlHelper.java b/src/main/java/org/openslx/util/XmlHelper.java
index 70c5be8..90d282b 100644
--- a/src/main/java/org/openslx/util/XmlHelper.java
+++ b/src/main/java/org/openslx/util/XmlHelper.java
@@ -3,6 +3,8 @@ package org.openslx.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -14,24 +16,29 @@ import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
-import org.apache.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.w3c.dom.Attr;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XmlHelper
{
- private final static Logger LOGGER = Logger.getLogger( XmlHelper.class );
+ private final static Logger LOGGER = LogManager.getLogger( XmlHelper.class );
// TODO check thread-safety
- public static final XPath XPath = XPathFactory.newInstance().newXPath();
+ private static final XPath XPath = XPathFactory.newInstance().newXPath();
private static DocumentBuilder dBuilder;
static {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+ dbFactory.setNamespaceAware( true );
dbFactory.setIgnoringComments( true );
try {
dBuilder = dbFactory.newDocumentBuilder();
@@ -40,17 +47,64 @@ public class XmlHelper
}
}
+ public static String globalXPathToLocalXPath( String xPath )
+ {
+ final StringBuilder exprBuilder = new StringBuilder();
+ final String[] elements = xPath.split( "/" );
+
+ for ( final String element : elements ) {
+ if ( !element.isEmpty() ) {
+ final Pattern arraySpecifierRegex = Pattern.compile( "^(.*)\\[(.*)\\]$" );
+ final Matcher arraySpecifierMatcher = arraySpecifierRegex.matcher( element );
+ final String elementName;
+ final String elementSpecifier;
+
+ if ( arraySpecifierMatcher.find() ) {
+ elementName = arraySpecifierMatcher.group( 1 );
+ elementSpecifier = arraySpecifierMatcher.group( 2 );
+ } else {
+ elementName = element;
+ elementSpecifier = null;
+ }
+
+ if ( !elementName.startsWith( "@" ) && !elementName.equals( "*" ) ) {
+ exprBuilder.append( "/*[local-name()='" + elementName + "']" );
+
+ } else {
+ exprBuilder.append( "/" + elementName );
+ }
+
+ if ( elementSpecifier != null && !elementSpecifier.isEmpty() ) {
+ exprBuilder.append( "[" + elementSpecifier + "]" );
+ }
+ }
+ }
+
+ return exprBuilder.toString();
+ }
+
+ public static XPathExpression compileXPath( String xPath ) throws XPathExpressionException
+ {
+ final String localXPath = XmlHelper.globalXPathToLocalXPath( xPath );
+ return XPath.compile( localXPath );
+ }
+
public static Document parseDocumentFromStream( InputStream is )
{
Document doc = null;
+
+ // read document from stream
try {
doc = dBuilder.parse( is );
} catch ( SAXException | IOException e ) {
- LOGGER.error( "Failed to parse input stream to document." );
+ doc = null;
}
- if ( doc == null )
- return null;
- doc.getDocumentElement().normalize();
+
+ // normalize parsed document
+ if ( doc != null ) {
+ doc.getDocumentElement().normalize();
+ }
+
return doc;
}
@@ -105,4 +159,51 @@ public class XmlHelper
return null;
}
}
+
+ public static Element getOrCreateElement( Document doc, Element parent, String nsUri, String nsName,
+ String name, String attrName, String attrValue )
+ {
+ final NodeList childList;
+ if ( nsUri == null ) {
+ childList = parent.getElementsByTagName( name );
+ } else {
+ childList = parent.getElementsByTagNameNS( nsUri, name );
+ }
+ Element element = null;
+ outer: for ( int i = 0; i < childList.getLength(); ++i ) {
+ Node n = childList.item( i );
+ if ( n.getNodeType() != Node.ELEMENT_NODE )
+ continue;
+ if ( attrName != null && attrValue != null ) {
+ for ( int ai = 0; ai < n.getAttributes().getLength(); ++ai ) {
+ Node attr = n.getAttributes().item( ai );
+ if ( attr.getNodeType() != Attr.ELEMENT_NODE )
+ continue;
+ Attr a = (Attr)attr;
+ if ( !attrName.equals( a.getLocalName() ) || !attrValue.equals( a.getValue() ) )
+ continue;
+ element = (Element)n;
+ break outer;
+ }
+ } else {
+ element = (Element)n;
+ break;
+ }
+ }
+ if ( element == null ) {
+ // Need a new <qemu:device alias="hostdev0">
+ if ( nsUri == null || nsName == null ) {
+ element = doc.createElement( name );
+ } else {
+ element = doc.createElementNS( nsUri, name );
+ element.setPrefix( nsName );
+ }
+ if ( attrName != null && attrValue != null ) {
+ element.setAttribute( attrName, attrValue );
+ }
+ parent.appendChild( element );
+ }
+ return element;
+ }
+
}