Azure XML shared library for Java - version 1.1.0
Azure XML provides shared primitives, abstractions, and helpers for XML.
Getting started
Prerequisites
- A Java Development Kit (JDK), version 8 or later.
Include the package
Include direct dependency
If you want to take dependency on a particular version of the library that is not present in the BOM, add the direct dependency to your project as follows.
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-xml</artifactId>
<version>1.1.0</version>
</dependency>
Key concepts
XmlSerializable
XmlSerializable
is used to define how an object is XML serialized and deserialized using stream-style serialization
where the object itself manages the logic for how it's handled with XML. The interface provides an instance-based
toXml
API which handles writing the object to an XmlWriter
and a static fromXml
API which implementations must
override to define how an object is created by reading from an XmlReader
.
XmlToken
XmlToken
is a basic enum that indicates the current state in an XML stream.
XmlReader
XmlReader
provides both basic, reading primitive and boxed primitive types, and convenience, reading an object, APIs
for reading XML. XmlReader
is provided to allow for any underlying XML parser to implement it, such as Woodstox or
XMLStreamReader, as long as the implementation passes the tests provided by this package's test-jar
(XmlReaderContractTests
).
XmlReader
is a simplified XML parser where it only supports reading element-by-element with the ability to retrieve
the namespace and attributes for that element. XmlReader
doesn't progress forward in the XML stream until
nextElement
is called, meaning that XmlReader.getIntElement
could be called indefinitely returning the same integer
without error until nextElement
progresses the XML stream forward.
XmlReader
doesn't take ownership of the XML input source and therefore won't close any resources if the XML is
provided using an InputStream
or Reader
.
XmlWriter
XmlWriter
provides basic APIs for writing XML. XmlWriter
is provided to allow for any underlying XML writer to
implement it, such as Woodstox or XMLStreamWriter, as long as the implementation passes the tests provided by this
package's test-jar (XmlWriterContractTests
).
XmlWriter
must be periodically flushed to ensure content written to it is flushed to the underlying container type,
generally an OutputStream
or Writer
. Failing to flush may result in content being lost. Closing the XmlWriter
will
also flush content, so it's best practice to use XmlWriter
in a try-with-resources block where the XmlWriter
will
be closed once it's finished being used.
XmlWriter
doesn't take ownership of the XML output source and therefore won't close any resources if the XML is being
written to an OutputStream
or Writer
.
XmlProvider
XmlProvider
is a service provider interface which allows for XmlReader
s and XmlWriter
s to be created using
implementations found on the classpath. XmlProvider
can also create the default implementations which are provided by
this package if an implementation isn't found on the classpath.
Examples
XmlSerializable
public class XmlSerializableExample implements XmlSerializable<XmlSerializableExample> {
private boolean aBooleanAttribute;
private Double aNullableDecimalAttribute;
private int anIntElement;
private String aStringElement;
@Override
public XmlWriter toXml(XmlWriter xmlWriter) throws XMLStreamException {
return toXml(xmlWriter, null);
}
public XmlWriter toXml(XmlWriter xmlWriter, String rootElementName) throws XMLStreamException {
// If the passed root element name is null or empty use the default root element name.
// This allows for scenarios where the model is defined with one XML root element name but other models use
// it with a separate XML element name.
rootElementName = (rootElementName == null || rootElementName.isEmpty()) ? "example" : rootElementName;
xmlWriter.writeStartElement(rootElementName);
// Writing attributes must happen first so that they are written to the object start element.
xmlWriter.writeBooleanAttribute("aBooleanAttribute", aBooleanAttribute);
xmlWriter.writeNumberAttribute("aNullableDecimalAttribute", aNullableDecimalAttribute);
xmlWriter.writeIntElement("anIntElement", anIntElement);
xmlWriter.writeStringElement("aStringElement", aStringElement);
return xmlWriter.writeEndElement();
}
public XmlSerializableExample fromXml(XmlReader xmlReader) throws XMLStreamException {
return fromXml(xmlReader, null);
}
public XmlSerializableExample fromXml(XmlReader xmlReader, String rootElementName) throws XMLStreamException {
rootElementName = (rootElementName == null || rootElementName.isEmpty()) ? "example" : rootElementName;
// readObject is a convenience method on XmlReader which prepares the XML for being read as an object.
// If the current token isn't an XmlToken.START_ELEMENT the next token element will be iterated to, if it's
// still not an XmlToken.START_ELEMENT after iterating to the next element an exception will be thrown. If
// the next element is an XmlToken.START_ELEMENT it will validate that the XML element matches the name
// expected, if the name doesn't match an exception will be thrown. If the element name matches the reader
// function will be called.
return xmlReader.readObject(rootElementName, reader -> {
// Since this class has no constructor reading to fields can be done inline.
// If the class had a constructor with arguments the recommendation is using local variables to track
// all field values.
XmlSerializableExample result = new XmlSerializableExample();
// Reading attributes must happen first so that the XmlReader is looking at the object start element.
result.aBooleanAttribute = reader.getBooleanAttribute(null, "aBooleanAttribute");
result.aNullableDecimalAttribute = reader.getNullableAttribute(null, "aNullableDecimalAttribute",
Double::parseDouble);
while (reader.nextElement() != XmlToken.END_ELEMENT) {
QName elementName = reader.getElementName();
// Since this object doesn't use namespaces we can work with the local part directly.
// If it had namespaces the full QName would need to be inspected.
String localPart = elementName.getLocalPart();
if ("anIntElement".equals(localPart)) {
result.anIntElement = reader.getIntElement();
} else if ("aStringElement".equals(localPart)) {
// getStringElement coalesces XML text and XML CData into a single string without needing to
// manage state.
result.aStringElement = reader.getStringElement();
} else {
// Skip element when the element is unknown.
reader.skipElement();
}
}
return result;
});
}
}
Next steps
Get started with Azure libraries that are built using Azure Core.
Troubleshooting
If you encounter any bugs, please file issues via GitHub Issues or checkout StackOverflow for Azure Java SDK.
Contributing
For details on contributing to this repository, see the contributing guide.
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
Azure SDK for Java