📄 saxoutputter.java
字号:
// Output node list as a document fragment.
elementContent(nodes, new NamespaceStack());
}
/**
* This will output a single JDOM nodes as a fragment of an XML
* document, firing off the SAX events that have been registered.
* <p>
* <strong>Warning</strong>: This method does not call the
* {@link ContentHandler#setDocumentLocator},
* {@link ContentHandler#startDocument} and
* {@link ContentHandler#endDocument} callbacks on the
* {@link #setContentHandler ContentHandler}. The user shall
* invoke these methods directly prior/after outputting the
* document fragments.</p>
*
* @param node the <code>Content</code> node to output.
*
* @throws JDOMException if any error occurred.
*
* @see #outputFragment(java.util.List)
*/
public void outputFragment(Content node) throws JDOMException {
if (node == null) {
return;
}
// Output single node as a document fragment.
elementContent(node, new NamespaceStack());
}
/**
* This parses a DTD declaration to fire the related events towards
* the registered handlers.
*
* @param document <code>JDOM Document</code> the DocType is to
* process.
*/
private void dtdEvents(Document document) throws JDOMException {
DocType docType = document.getDocType();
// Fire DTD-related events only if handlers have been registered.
if ((docType != null) &&
((dtdHandler != null) || (declHandler != null))) {
// Build a dummy XML document that only references the DTD...
String dtdDoc = new XMLOutputter().outputString(docType);
try {
// And parse it to fire DTD events.
createDTDParser().parse(new InputSource(
new StringReader(dtdDoc)));
// We should never reach this point as the document is
// ill-formed; it does not have any root element.
}
catch (SAXParseException e) {
// Expected exception: There's no root element in document.
}
catch (SAXException e) {
throw new JDOMException("DTD parsing error", e);
}
catch (IOException e) {
throw new JDOMException("DTD parsing error", e);
}
}
}
/**
* <p>
* This method tells you the line of the XML file being parsed.
* For an in-memory document, it's meaningless. The location
* is only valid for the current parsing lifecycle, but
* the document has already been parsed. Therefore, it returns
* -1 for both line and column numbers.
* </p>
*
* @param document JDOM <code>Document</code>.
*/
private void documentLocator(Document document) {
locator = new JDOMLocator();
String publicID = null;
String systemID = null;
if (document != null) {
DocType docType = document.getDocType();
if (docType != null) {
publicID = docType.getPublicID();
systemID = docType.getSystemID();
}
}
locator.setPublicId(publicID);
locator.setSystemId(systemID);
locator.setLineNumber(-1);
locator.setColumnNumber(-1);
contentHandler.setDocumentLocator(locator);
}
/**
* <p>
* This method is always the second method of all callbacks in
* all handlers to be invoked (setDocumentLocator is always first).
* </p>
*/
private void startDocument() throws JDOMException {
try {
contentHandler.startDocument();
}
catch (SAXException se) {
throw new JDOMException("Exception in startDocument", se);
}
}
/**
* <p>
* Always the last method of all callbacks in all handlers
* to be invoked.
* </p>
*/
private void endDocument() throws JDOMException {
try {
contentHandler.endDocument();
// reset locator
locator = null;
}
catch (SAXException se) {
throw new JDOMException("Exception in endDocument", se);
}
}
/**
* <p>
* This will invoke the <code>ContentHandler.processingInstruction</code>
* callback when a processing instruction is encountered.
* </p>
*
* @param pi <code>ProcessingInstruction</code> containing target and data.
*/
private void processingInstruction(ProcessingInstruction pi)
throws JDOMException {
if (pi != null) {
String target = pi.getTarget();
String data = pi.getData();
try {
contentHandler.processingInstruction(target, data);
}
catch (SAXException se) {
throw new JDOMException(
"Exception in processingInstruction", se);
}
}
}
/**
* <p>
* This will recursively invoke all of the callbacks for a particular
* element.
* </p>
*
* @param element <code>Element</code> used in callbacks.
* @param namespaces <code>List</code> stack of Namespaces in scope.
*/
private void element(Element element, NamespaceStack namespaces)
throws JDOMException {
// used to check endPrefixMapping
int previouslyDeclaredNamespaces = namespaces.size();
// contentHandler.startPrefixMapping()
Attributes nsAtts = startPrefixMapping(element, namespaces);
// contentHandler.startElement()
startElement(element, nsAtts);
// handle content in the element
elementContent(element.getContent(), namespaces);
// update locator
if (locator != null) {
locator.setNode(element);
}
// contentHandler.endElement()
endElement(element);
// contentHandler.endPrefixMapping()
endPrefixMapping(namespaces, previouslyDeclaredNamespaces);
}
/**
* <p>
* This will invoke the <code>ContentHandler.startPrefixMapping</code>
* callback
* when a new namespace is encountered in the <code>Document</code>.
* </p>
*
* @param element <code>Element</code> used in callbacks.
* @param namespaces <code>List</code> stack of Namespaces in scope.
*
* @return <code>Attributes</code> declaring the namespaces local to
* <code>element</code> or <code>null</code>.
*/
private Attributes startPrefixMapping(Element element,
NamespaceStack namespaces)
throws JDOMException {
AttributesImpl nsAtts = null; // The namespaces as xmlns attributes
Namespace ns = element.getNamespace();
if (ns != Namespace.XML_NAMESPACE) {
String prefix = ns.getPrefix();
String uri = namespaces.getURI(prefix);
if (!ns.getURI().equals(uri)) {
namespaces.push(ns);
nsAtts = this.addNsAttribute(nsAtts, ns);
try {
contentHandler.startPrefixMapping(prefix, ns.getURI());
}
catch (SAXException se) {
throw new JDOMException(
"Exception in startPrefixMapping", se);
}
}
}
// Fire additional namespace declarations
List additionalNamespaces = element.getAdditionalNamespaces();
if (additionalNamespaces != null) {
Iterator itr = additionalNamespaces.iterator();
while (itr.hasNext()) {
ns = (Namespace)itr.next();
String prefix = ns.getPrefix();
String uri = namespaces.getURI(prefix);
if (!ns.getURI().equals(uri)) {
namespaces.push(ns);
nsAtts = this.addNsAttribute(nsAtts, ns);
try {
contentHandler.startPrefixMapping(prefix, ns.getURI());
}
catch (SAXException se) {
throw new JDOMException(
"Exception in startPrefixMapping", se);
}
}
}
}
return nsAtts;
}
/**
* <p>
* This will invoke the <code>endPrefixMapping</code> callback in the
* <code>ContentHandler</code> when a namespace is goes out of scope
* in the <code>Document</code>.
* </p>
*
* @param namespaces <code>List</code> stack of Namespaces in scope.
* @param previouslyDeclaredNamespaces number of previously declared
* namespaces
*/
private void endPrefixMapping(NamespaceStack namespaces,
int previouslyDeclaredNamespaces)
throws JDOMException {
while (namespaces.size() > previouslyDeclaredNamespaces) {
String prefix = namespaces.pop();
try {
contentHandler.endPrefixMapping(prefix);
}
catch (SAXException se) {
throw new JDOMException("Exception in endPrefixMapping", se);
}
}
}
/**
* <p>
* This will invoke the <code>startElement</code> callback
* in the <code>ContentHandler</code>.
* </p>
*
* @param element <code>Element</code> used in callbacks.
* @param nsAtts <code>List</code> of namespaces to declare with
* the element or <code>null</code>.
*/
private void startElement(Element element, Attributes nsAtts)
throws JDOMException {
String namespaceURI = element.getNamespaceURI();
String localName = element.getName();
String rawName = element.getQualifiedName();
// Allocate attribute list.
AttributesImpl atts = (nsAtts != null)?
new AttributesImpl(nsAtts): new AttributesImpl();
List attributes = element.getAttributes();
Iterator i = attributes.iterator();
while (i.hasNext()) {
Attribute a = (Attribute) i.next();
atts.addAttribute(a.getNamespaceURI(),
a.getName(),
a.getQualifiedName(),
getAttributeTypeName(a.getAttributeType()),
a.getValue());
}
try {
contentHandler.startElement(namespaceURI, localName, rawName, atts);
}
catch (SAXException se) {
throw new JDOMException("Exception in startElement", se);
}
}
/**
* <p>
* This will invoke the <code>endElement</code> callback
* in the <code>ContentHandler</code>.
* </p>
*
* @param element <code>Element</code> used in callbacks.
*/
private void endElement(Element element) throws JDOMException {
String namespaceURI = element.getNamespaceURI();
String localName = element.getName();
String rawName = element.getQualifiedName();
try {
contentHandler.endElement(namespaceURI, localName, rawName);
}
catch (SAXException se) {
throw new JDOMException("Exception in endElement", se);
}
}
/**
* <p>
* This will invoke the callbacks for the content of an element.
* </p>
*
* @param content element content as a <code>List</code> of nodes.
* @param namespaces <code>List</code> stack of Namespaces in scope.
*/
private void elementContent(List content, NamespaceStack namespaces)
throws JDOMException {
for (Iterator i=content.iterator(); i.hasNext(); ) {
Object obj = i.next();
if (obj instanceof Content) {
this.elementContent((Content)obj, namespaces);
}
else {
// Not a valid element child. This could happen with
// application-provided lists which may contain non
// JDOM objects.
handleError(new JDOMException(
"Invalid element content: " + obj));
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -