diff options
Diffstat (limited to 'src/main/java/org/openslx/util/XmlHelper.java')
-rw-r--r-- | src/main/java/org/openslx/util/XmlHelper.java | 115 |
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; + } + } |