.NET and matching element name with wildcard using XPath

This is similar to matching a name space with a wildcard.

'This is the node we are searching in
Dim someXmlNode As XmlNode = FetchXmlNode() 
Dim xPathExpr As String = String.Empty
 
'find all nodes with names that starts with nisse_
xPathExpr = ".//*[starts-with(name(), 'nisse_')]"
 
'loop through all elements that matches our XPath
For Each elementWithNisse As XmlNode In someXmlNode.SelectNodes(xPathExpr)
 
    AndHereAMiracleHappens(elementWithNisse)
 
Next

.NET and matching namespace with wildcard using XPath

.NET framework’s XslCompiledTransform only supports XPath and XSLT 1.0.

With XPath 1.0 ‘*’ is allowed to select all elements and nisse:* is allowed to select all elements in the namespace bound to the prefix ‘nisse’ but *:nisse to select ‘nisse’ elements in all
namespaces is not allowed in XPath 1.0, see http://www.w3.org/TR/xpath#node-tests.

And here is an example in vb.net where InnerText is read from the nameOfElementToFind in any name space

' This is the xmlnode the search is done with
Dim node As XmlNode = FetchSomeNode()
 
Dim innerTextFromNode As String = String.Empty
Dim xPathToSearchFor As String = String.Empty
 
'Will find all direct decendants nameOfElementToFind in any name space
xPathToSearchFor = "*[local-name() 'nameOfElementToFind']" 
 
'Will find all nameOfElementToFind in any name space and anywhere under this node
xPathToSearchFor = ".//*[local-name() 'nameOfElementToFind']" 
 
'Will find all nameOfElementToFind in any name space and anywhere in the document the node belongs to
xPathToSearchFor = "//*[local-name() 'nameOfElementToFind']"
 
If (node IsNot Nothing) Then
	innerTextFromNode = node.selectSingleNode(xPathToSearchIn).InnerText
End If

Java: Getting the Document from a Node or Element

When we for instance wishes to add a new element we need to pass along the document. If we have a element or a node we can get the document that way. Simply call getOwnerDocument and we are good.

Element element = //code to get a element
Node node = //code to get a node
 
//document from Node
Document document = node.getOwnerDocument();
 
//document from a Element
Document document = element.getOwnerDocument();

Java: Adding a Element under an Element (or Converting a Element to a Node)

When using Document a Element can only be appended with a Node, but what if we have a Element ?

Easy, Element extends Node so just pass the Element along and all is well

import org.w3c.dom.Document;
import org.w3c.dom.Element;
 
Document doc;
Element newElement;
Element oldElement; //code to find that
newElement = doc.createElement("tag");
oldElement.appendChild(newElement);

Java org.w3c.dom.Document add attribute to Node(s) (Element(s))

This example will add((or update if exists) a attribute to one or several Element(s).

NodeList nodeList = document.getElementsByTagName("tagToFind");
for (int i = 0; i < nodeList.getLength(); i++){
	( (Element)nodeList.item(i) ).setAttribute("attributeNameToAdd", "attributeStringValueToAdd");
}

And what the manual (jdk6u30) says about setAttribute:

setAttribute

void setAttribute(String name,
String value)
throws DOMException

Adds a new attribute. If an attribute with that name is already present in the element, its value is changed to be that of the value parameter. This value is a simple string; it is not parsed as it is being set. So any markup (such as syntax to be recognized as an entity reference) is treated as literal text, and needs to be appropriately escaped by the implementation when it is written out. In order to assign an attribute value that contains entity references, the user must create an Attr node plus any Text and EntityReference nodes, build the appropriate subtree, and use setAttributeNode to assign it as the value of an attribute.
To set an attribute with a qualified name and namespace URI, use the setAttributeNS method.

Parameters:
name – The name of the attribute to create or alter.
value – Value to set in string form.
Throws:
DOMException – INVALID_CHARACTER_ERR: Raised if the specified name is not an XML name according to the XML version in use specified in the Document.xmlVersion attribute.
NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.

Java org.w3c.dom.Document getting an attribule as a string from a Node (Element)

This example shows how to get a list of attribute values from all elements with a given name.
Might not fit your needs but it should give a good idea on how to do things that are similar to this (like simply get a attribute from a singe Element).

public static List<String> getAttributesByElementName(String attribute, String element, String xmlString){
	ArrayList<Integer> listToReturn = new ArrayList<Integer>();
 
	Document document = XmlUtils.loadXMLAsDom(xmlString);
	NodeList nodeList = document.getElementsByTagName(element);
	for (int i = 0; i < nodeList.getLength(); i++){
		String currAttribute = ( (Element)nodeList.item(i) ).getAttribute(attribute);
		if ( !currAttribute.isEmpty() ){
			listToReturn.add(currAttribute );
		}
	}
	return listToReturn;
}

Java org.w3c.dom.Document output nicely formatted

This will print a nicely formatted (indented, linebreaks etc) i.e. more human readable xml document.

public static String getNiceLyFormattedXMLDocument(Document doc) throws IOException, TransformerException {
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer = tf.newTransformer();
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
    transformer.setOutputProperty(OutputKeys.METHOD, "xml");
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
 
    Writer stringWriter = new StringWriter();
    StreamResult streamResult = new StreamResult(stringWriter);
    transformer.transform(new DOMSource(doc), streamResult);
    String result = stringWriter.toString();
 
    return result;
}

Java get a XML document (file, string or inputstream) as a org.w3c.dom.Document

This helper function will read a xml string (or any InputStream) and create a Document from this.

public static Document loadXMLAsDom(String xml){
	return loadXMLAsDom(new ByteArrayInputStream(xml.getBytes()));
}
public static Document loadXMLAsDom(InputStream inputStream) {
	DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
	documentBuilderFactory.setNamespaceAware(true);
	DocumentBuilder documentBuilder = null;
	Document document = null;
	try{
		documentBuilder  = documentBuilderFactory.newDocumentBuilder();
		document = documentBuilder.parse(new InputSource(inputStream)); //use InputSource here to get better support for encodings
		inputStream.close();
	}
	catch (ParserConfigurationException e){
		System.out.println("loadXMLAsDom got a ParserConfigurationException! "); e.printStackTrace;
	}
	catch (IOException e){
		System.out.println("loadXMLAsDom got a IOException! "); e.printStackTrace;
	}
	catch (SAXException e){
		System.out.println("loadXMLAsDom got a SAXException! "); e.printStackTrace;
	}		
	return document;
}

SimpleXml save formated output

When using the SimpleXml->asXML(‘file.xml’) the output is simply written onto one line.
like

<?xml version="1.0" encoding="UTF-8"?>
<product><companyId>1</companyId><productId>1:1</productId></product>

There is nothing wrong with this but if you add line breaks and indentations the xml file looks better and is easier to (manually) read.
Unfortunately there is no way to do this using SimpleXML, but there is a quick and dirty way to do this; and that is to import the SimpleXMLobject to a DOMElement and do it there so some example code

$xmlDom = dom_import_simplexml($simpleXmlObject);
$xmlDom->formatOutput = true;
$xmlDom->save("test.xml");

This would result in an xml file looking like this:

<?xml version="1.0" encoding="UTF-8"?>
<product>
	<companyId>1</companyId>
	<productId>1:1</productId>
</product>

Easier to read but takes some extra space on the disk (might not be much but it is good to remember).