name.pehl.totoe.xml.client.XmlParser Maven / Gradle / Ivy
package name.pehl.totoe.xml.client;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import name.pehl.totoe.xml.client.internal.XmlParserImpl;
/**
* XML parser with namespace support for turning an XML input string into a
* {@link Document} instance.
*
* Default namespace:
* If you want to parse a XML document with a default namespace and you want to
* reference the default namespace later on in XPath expressions. You have to
* provide a prefix for the default namespace. Suppose you have the following
* XML document:
*
*
* <?xml version="1.0" encoding="UTF-8"?>
* <swissArmyKnife xmlns="http://code.google.com/p/totoe"
* xmlns:foo="http://code.google.com/p/totoe/foo"
* xmlns:bar="http://code.google.com/p/totoe/bar"
* id="B001DZTJRQ">
* <!--
* XML that has erything inside. Just like the Wenger 16999 Swiss Army Knife
* http://www.amazon.com/Wenger-16999-Swiss-Army-Knife/dp/B001DZTJRQ/
* -->
* <description><![CDATA[
* Call it what you will, it's a knife that's unrivaled, impractical,
* and enormous, it's more knife than one can carry or would fit in one's pocket
* ]]></description>
* <!-- long live the metric system! -->
* <foo:dimensions foo:unit="cm">11.8 x 10.8 x 4.3</foo:dimensions>
* <bar:weight bar:unit="g">700</bar:weight>
* <functions number="more than you'll ever need">
* <rocketLauncher kind="advanced" foo:range="intercontinental" bar:dangerous="indeed">5</rocketLauncher>
* <calculator eval="1 &< 2">2 &> 1</calculator>
* <bttf:fluxCapacitor xmlns:bttf="http://en.wikipedia.org/wiki/Back_to_the_Future">
* <bttf:power unit="gigawatts">1.21</bttf:power>
* </bttf:fluxCapacitor>
* </functions>
* </swissArmyKnife>
*
*
* To parse the XML use the following code:
*
*
* String xml = ...;
* String namespaces = "xmlns:default=\"http://code.google.com/p/totoe\" "
* + "xmlns:foo=\"http://code.google.com/p/totoe/foo\" "
* + "xmlns:bar=\"http://code.google.com/p/totoe/bar\" "
* + "xmlns:bttf=\"http://en.wikipedia.org/wiki/Back_to_the_Future\"";
* Document document = new XmlParser().parse(xml, namespaces);
*
*
* @author $Author$
* @version $Date$ $Revision: 623
* $
*/
public class XmlParser
{
private XmlParserImpl impl = new XmlParserImpl();
// ---------------------------------------------------------- parse methods
/**
* Parses the given xml to an instance of {@link Document}.
*
* @param xml
* @return
* @throws XmlParseException
* if an error occured while parsing
*/
public Document parse(String xml) throws XmlParseException
{
return impl.parse(xml, null);
}
/**
* Parses the given xml to an instance of {@link Document} using the
* specified namespaces. The namespaces have to be specified as a
* whilespace-seperated list of namespace declarations as those would appear
* in an XML document (except for the default namespace - see below).
*
* If your xml has a default namespace and you want to reference it later on
* in XPath expressions you have to provide a prefix for that default
* namespace. In case you have the following xml:
*
*
* <?xml version="1.0" encoding="UTF-8"?>
* <lotteryTicket xmlns="http://code.google.com/p/totoe"
* xmlns:foo="http://code.google.com/p/totoe/foo"
* xmlns:bar="http://code.google.com/p/totoe/bar">
* ...
* </lotteryTicket>
*
*
* Use this code to parse it:
*
*
* String xml = ...;
* String namespaces = "xmlns:default=\"http://code.google.com/p/totoe\" "
* + "xmlns:foo=\"http://code.google.com/p/totoe/foo\" "
* + "xmlns:bar=\"http://code.google.com/p/totoe/bar\"";
* Document document = new XmlParser().parse(xml, namespaces);
*
*
* @param xml
* @param namespaces
* a whilespace-seperated list of namespace declarations as those
* would appear in an XML document.
* @return
* @throws XmlParseException
* if an error occured while parsing
*/
public Document parse(String xml, String namespaces) throws XmlParseException
{
return impl.parse(xml, namespaces);
}
/**
* Parses the given xml to an instance of {@link Document} using the
* specified namespaces. The namespaces have to be specified as a map with
* the namespace prefix as key and the namespace uri as value.
*
* If your xml has a default namespace and you want to reference it later on
* in xpath expressions you have to provide a prefix for that default
* namespace. In case you have the following xml:
*
*
* <?xml version="1.0" encoding="UTF-8"?>
* <lotteryTicket xmlns="http://code.google.com/p/totoe"
* xmlns:foo="http://code.google.com/p/totoe/foo"
* xmlns:bar="http://code.google.com/p/totoe/bar">
* ...
* </lotteryTicket>
*
*
* Use this code to parse it:
*
*
* String xml = ...;
* Map<String, String> namespaces = new HashMap<String, String>();
* namespaces.put("default", "http://code.google.com/p/totoe");
* namespaces.put("foo", "http://code.google.com/p/totoe/foo");
* namespaces.put("bar", "http://code.google.com/p/totoe/bar");
* Document document = new XmlParser().parse(xml, namespaces);
*
*
* @param xml
* @param namespaces
* a map with the namespace prefix as key and the namespace uri
* as value.
* @return
* @throws XmlParseException
* if an error occured while parsing
*/
public Document parse(String xml, Map namespaces) throws XmlParseException
{
return impl.parse(xml, getNamespaces(namespaces));
}
// --------------------------------------------------------- helper methods
/**
* Converts the specifed namespaces in the map to a whilespace-seperated
* list of namespace declarations as those would appear in an XML document.
*
* @param namespaces
* Namespaces with the namespace prefix as key and the namespace
* uri as value.
* @return a whilespace-seperated list of namespace declarations as those
* would appear in an XML document or null
if the
* namespaces argument was null
or empty.
*/
protected String getNamespaces(Map namespaces)
{
String result = null;
if (namespaces != null && !namespaces.isEmpty())
{
StringBuilder builder = new StringBuilder();
for (Iterator> iter = namespaces.entrySet().iterator(); iter.hasNext();)
{
Entry entry = iter.next();
String prefix = entry.getKey();
String uri = entry.getValue();
if (prefix != null && prefix.length() != 0 && uri != null && uri.length() != 0)
{
builder.append("xmlns:");
builder.append(prefix);
builder.append("=\"");
builder.append(uri);
builder.append("\"");
if (iter.hasNext())
{
builder.append(" ");
}
}
}
result = builder.toString();
}
return result;
}
}