下面列出了org.w3c.dom.DOMImplementation#hasFeature ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public static String toXml(Document domDoc) throws TransformerException {
DOMImplementation domImplementation = domDoc.getImplementation();
if (domImplementation.hasFeature("LS", "3.0") && domImplementation.hasFeature("Core", "2.0")) {
DOMImplementationLS domImplementationLS = (DOMImplementationLS) domImplementation.getFeature("LS", "3.0");
LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
DOMConfiguration domConfiguration = lsSerializer.getDomConfig();
if (domConfiguration.canSetParameter("xml-declaration", Boolean.TRUE))
lsSerializer.getDomConfig().setParameter("xml-declaration", Boolean.FALSE);
if (domConfiguration.canSetParameter("format-pretty-print", Boolean.TRUE)) {
lsSerializer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
LSOutput lsOutput = domImplementationLS.createLSOutput();
lsOutput.setEncoding("UTF-8");
StringWriter stringWriter = new StringWriter();
lsOutput.setCharacterStream(stringWriter);
lsSerializer.write(domDoc, lsOutput);
return stringWriter.toString();
}
}
return toXml((Node) domDoc);
}
private void format(Document document, Writer writer) {
DOMImplementation implementation = document.getImplementation();
if(implementation.hasFeature(LS_FEATURE_KEY, LS_FEATURE_VERSION) && implementation.hasFeature(CORE_FEATURE_KEY, CORE_FEATURE_VERSION)) {
DOMImplementationLS implementationLS = (DOMImplementationLS) implementation.getFeature(LS_FEATURE_KEY, LS_FEATURE_VERSION);
LSSerializer serializer = implementationLS.createLSSerializer();
DOMConfiguration configuration = serializer.getDomConfig();
configuration.setParameter("format-pretty-print", Boolean.TRUE);
configuration.setParameter("comments", preserveComments);
LSOutput output = implementationLS.createLSOutput();
output.setEncoding("UTF-8");
output.setCharacterStream(writer);
serializer.write(document, output);
}
}
private static void _initFeature (@Nonnull final EXMLDOMFeature eFeature)
{
final DOMImplementation aDOMImplementation = XMLFactory.getDOMImplementation ();
for (final EXMLDOMFeatureVersion eFeatureVersion : EXMLDOMFeatureVersion.values ())
{
if (aDOMImplementation.hasFeature (eFeature.getID (), eFeatureVersion.getID ()))
s_aSupportedFeatures.get (eFeatureVersion).add (eFeature.getID ());
else
if (aDOMImplementation.hasFeature (eFeature.getPlusFeature (), eFeatureVersion.getID ()))
s_aSupportedFeatures.get (eFeatureVersion).add (eFeature.getPlusFeature ());
}
}
boolean testImpl(DOMImplementation impl, String features) {
StringTokenizer st = new StringTokenizer(features);
String feature = null;
String version = null;
if (st.hasMoreTokens()) {
feature = st.nextToken();
}
while (feature != null) {
boolean isVersion = false;
if (st.hasMoreTokens()) {
char c;
version = st.nextToken();
c = version.charAt(0);
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
isVersion = true;
}
} else {
version = null;
}
if (isVersion) {
if (!impl.hasFeature(feature, version)) {
return false;
}
if (st.hasMoreTokens()) {
feature = st.nextToken();
} else {
feature = null;
}
} else {
if (!impl.hasFeature(feature, null)) {
return false;
}
feature = version;
}
}
return true;
}
/**
* Obtain the XPath-model parent of a DOM node -- ownerElement for Attrs,
* parent for other nodes.
* <p>
* Background: The DOM believes that you must be your Parent's
* Child, and thus Attrs don't have parents. XPath said that Attrs
* do have their owning Element as their parent. This function
* bridges the difference, either by using the DOM Level 2 ownerElement
* function or by using a "silly and expensive function" in Level 1
* DOMs.
* <p>
* (There's some discussion of future DOMs generalizing ownerElement
* into ownerNode and making it work on all types of nodes. This
* still wouldn't help the users of Level 1 or Level 2 DOMs)
* <p>
*
* @param node Node whose XPath parent we want to obtain
*
* @return the parent of the node, or the ownerElement if it's an
* Attr node, or null if the node is an orphan.
*
* @throws RuntimeException if the Document has no root element.
* This can't arise if the Document was created
* via the DOM Level 2 factory methods, but is possible if other
* mechanisms were used to obtain it
*/
public static Node getParentOfNode(Node node) throws RuntimeException
{
Node parent;
short nodeType = node.getNodeType();
if (Node.ATTRIBUTE_NODE == nodeType)
{
Document doc = node.getOwnerDocument();
/*
TBD:
if(null == doc)
{
throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT, null));//"Attribute child does not have an owner document!");
}
*/
// Given how expensive the tree walk may be, we should first ask
// whether this DOM can answer the question for us. The additional
// test does slow down Level 1 DOMs slightly. DOMHelper2, which
// is currently specialized for Xerces, assumes it can use the
// Level 2 solution. We might want to have an intermediate stage,
// which would assume DOM Level 2 but not assume Xerces.
//
// (Shouldn't have to check whether impl is null in a compliant DOM,
// but let's be paranoid for a moment...)
DOMImplementation impl=doc.getImplementation();
if(impl!=null && impl.hasFeature("Core","2.0"))
{
parent=((Attr)node).getOwnerElement();
return parent;
}
// DOM Level 1 solution, as fallback. Hugely expensive.
Element rootElem = doc.getDocumentElement();
if (null == rootElem)
{
throw new RuntimeException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT,
null)); //"Attribute child does not have an owner document element!");
}
parent = locateAttrParent(rootElem, node);
}
else
{
parent = node.getParentNode();
// if((Node.DOCUMENT_NODE != nodeType) && (null == parent))
// {
// throw new RuntimeException("Child does not have parent!");
// }
}
return parent;
}
boolean testImpl(DOMImplementation impl, String features) {
StringTokenizer st = new StringTokenizer(features);
String feature = null;
String version = null;
if (st.hasMoreTokens()) {
feature = st.nextToken();
}
while (feature != null) {
boolean isVersion = false;
if (st.hasMoreTokens()) {
char c;
version = st.nextToken();
c = version.charAt(0);
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
isVersion = true;
}
} else {
version = null;
}
if (isVersion) {
if (!impl.hasFeature(feature, version)) {
return false;
}
if (st.hasMoreTokens()) {
feature = st.nextToken();
} else {
feature = null;
}
} else {
if (!impl.hasFeature(feature, null)) {
return false;
}
feature = version;
}
}
return true;
}
boolean testImpl(DOMImplementation impl, String features) {
StringTokenizer st = new StringTokenizer(features);
String feature = null;
String version = null;
if (st.hasMoreTokens()) {
feature = st.nextToken();
}
while (feature != null) {
boolean isVersion = false;
if (st.hasMoreTokens()) {
char c;
version = st.nextToken();
c = version.charAt(0);
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
isVersion = true;
}
} else {
version = null;
}
if (isVersion) {
if (!impl.hasFeature(feature, version)) {
return false;
}
if (st.hasMoreTokens()) {
feature = st.nextToken();
} else {
feature = null;
}
} else {
if (!impl.hasFeature(feature, null)) {
return false;
}
feature = version;
}
}
return true;
}
/**
* Obtain the XPath-model parent of a DOM node -- ownerElement for Attrs,
* parent for other nodes.
* <p>
* Background: The DOM believes that you must be your Parent's
* Child, and thus Attrs don't have parents. XPath said that Attrs
* do have their owning Element as their parent. This function
* bridges the difference, either by using the DOM Level 2 ownerElement
* function or by using a "silly and expensive function" in Level 1
* DOMs.
* <p>
* (There's some discussion of future DOMs generalizing ownerElement
* into ownerNode and making it work on all types of nodes. This
* still wouldn't help the users of Level 1 or Level 2 DOMs)
* <p>
*
* @param node Node whose XPath parent we want to obtain
*
* @return the parent of the node, or the ownerElement if it's an
* Attr node, or null if the node is an orphan.
*
* @throws RuntimeException if the Document has no root element.
* This can't arise if the Document was created
* via the DOM Level 2 factory methods, but is possible if other
* mechanisms were used to obtain it
*/
public static Node getParentOfNode(Node node) throws RuntimeException
{
Node parent;
short nodeType = node.getNodeType();
if (Node.ATTRIBUTE_NODE == nodeType)
{
Document doc = node.getOwnerDocument();
/*
TBD:
if(null == doc)
{
throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT, null));//"Attribute child does not have an owner document!");
}
*/
// Given how expensive the tree walk may be, we should first ask
// whether this DOM can answer the question for us. The additional
// test does slow down Level 1 DOMs slightly. DOMHelper2, which
// is currently specialized for Xerces, assumes it can use the
// Level 2 solution. We might want to have an intermediate stage,
// which would assume DOM Level 2 but not assume Xerces.
//
// (Shouldn't have to check whether impl is null in a compliant DOM,
// but let's be paranoid for a moment...)
DOMImplementation impl=doc.getImplementation();
if(impl!=null && impl.hasFeature("Core","2.0"))
{
parent=((Attr)node).getOwnerElement();
return parent;
}
// DOM Level 1 solution, as fallback. Hugely expensive.
Element rootElem = doc.getDocumentElement();
if (null == rootElem)
{
throw new RuntimeException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT,
null)); //"Attribute child does not have an owner document element!");
}
parent = locateAttrParent(rootElem, node);
}
else
{
parent = node.getParentNode();
// if((Node.DOCUMENT_NODE != nodeType) && (null == parent))
// {
// throw new RuntimeException("Child does not have parent!");
// }
}
return parent;
}
boolean testImpl(DOMImplementation impl, String features) {
StringTokenizer st = new StringTokenizer(features);
String feature = null;
String version = null;
if (st.hasMoreTokens()) {
feature = st.nextToken();
}
while (feature != null) {
boolean isVersion = false;
if (st.hasMoreTokens()) {
char c;
version = st.nextToken();
c = version.charAt(0);
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
isVersion = true;
}
} else {
version = null;
}
if (isVersion) {
if (!impl.hasFeature(feature, version)) {
return false;
}
if (st.hasMoreTokens()) {
feature = st.nextToken();
} else {
feature = null;
}
} else {
if (!impl.hasFeature(feature, null)) {
return false;
}
feature = version;
}
}
return true;
}
boolean testImpl(DOMImplementation impl, String features) {
StringTokenizer st = new StringTokenizer(features);
String feature = null;
String version = null;
if (st.hasMoreTokens()) {
feature = st.nextToken();
}
while (feature != null) {
boolean isVersion = false;
if (st.hasMoreTokens()) {
char c;
version = st.nextToken();
c = version.charAt(0);
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
isVersion = true;
}
} else {
version = null;
}
if (isVersion) {
if (!impl.hasFeature(feature, version)) {
return false;
}
if (st.hasMoreTokens()) {
feature = st.nextToken();
} else {
feature = null;
}
} else {
if (!impl.hasFeature(feature, null)) {
return false;
}
feature = version;
}
}
return true;
}
boolean testImpl(DOMImplementation impl, String features) {
StringTokenizer st = new StringTokenizer(features);
String feature = null;
String version = null;
if (st.hasMoreTokens()) {
feature = st.nextToken();
}
while (feature != null) {
boolean isVersion = false;
if (st.hasMoreTokens()) {
char c;
version = st.nextToken();
c = version.charAt(0);
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
isVersion = true;
}
} else {
version = null;
}
if (isVersion) {
if (!impl.hasFeature(feature, version)) {
return false;
}
if (st.hasMoreTokens()) {
feature = st.nextToken();
} else {
feature = null;
}
} else {
if (!impl.hasFeature(feature, null)) {
return false;
}
feature = version;
}
}
return true;
}
boolean testImpl(DOMImplementation impl, String features) {
StringTokenizer st = new StringTokenizer(features);
String feature = null;
String version = null;
if (st.hasMoreTokens()) {
feature = st.nextToken();
}
while (feature != null) {
boolean isVersion = false;
if (st.hasMoreTokens()) {
char c;
version = st.nextToken();
c = version.charAt(0);
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
isVersion = true;
}
} else {
version = null;
}
if (isVersion) {
if (!impl.hasFeature(feature, version)) {
return false;
}
if (st.hasMoreTokens()) {
feature = st.nextToken();
} else {
feature = null;
}
} else {
if (!impl.hasFeature(feature, null)) {
return false;
}
feature = version;
}
}
return true;
}
boolean testImpl(DOMImplementation impl, String features) {
StringTokenizer st = new StringTokenizer(features);
String feature = null;
String version = null;
if (st.hasMoreTokens()) {
feature = st.nextToken();
}
while (feature != null) {
boolean isVersion = false;
if (st.hasMoreTokens()) {
char c;
version = st.nextToken();
c = version.charAt(0);
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
isVersion = true;
}
} else {
version = null;
}
if (isVersion) {
if (!impl.hasFeature(feature, version)) {
return false;
}
if (st.hasMoreTokens()) {
feature = st.nextToken();
} else {
feature = null;
}
} else {
if (!impl.hasFeature(feature, null)) {
return false;
}
feature = version;
}
}
return true;
}
/**
* Obtain the XPath-model parent of a DOM node -- ownerElement for Attrs,
* parent for other nodes.
* <p>
* Background: The DOM believes that you must be your Parent's
* Child, and thus Attrs don't have parents. XPath said that Attrs
* do have their owning Element as their parent. This function
* bridges the difference, either by using the DOM Level 2 ownerElement
* function or by using a "silly and expensive function" in Level 1
* DOMs.
* <p>
* (There's some discussion of future DOMs generalizing ownerElement
* into ownerNode and making it work on all types of nodes. This
* still wouldn't help the users of Level 1 or Level 2 DOMs)
* <p>
*
* @param node Node whose XPath parent we want to obtain
*
* @return the parent of the node, or the ownerElement if it's an
* Attr node, or null if the node is an orphan.
*
* @throws RuntimeException if the Document has no root element.
* This can't arise if the Document was created
* via the DOM Level 2 factory methods, but is possible if other
* mechanisms were used to obtain it
*/
public static Node getParentOfNode(Node node) throws RuntimeException
{
Node parent;
short nodeType = node.getNodeType();
if (Node.ATTRIBUTE_NODE == nodeType)
{
Document doc = node.getOwnerDocument();
/*
TBD:
if(null == doc)
{
throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT, null));//"Attribute child does not have an owner document!");
}
*/
// Given how expensive the tree walk may be, we should first ask
// whether this DOM can answer the question for us. The additional
// test does slow down Level 1 DOMs slightly. DOMHelper2, which
// is currently specialized for Xerces, assumes it can use the
// Level 2 solution. We might want to have an intermediate stage,
// which would assume DOM Level 2 but not assume Xerces.
//
// (Shouldn't have to check whether impl is null in a compliant DOM,
// but let's be paranoid for a moment...)
DOMImplementation impl=doc.getImplementation();
if(impl!=null && impl.hasFeature("Core","2.0"))
{
parent=((Attr)node).getOwnerElement();
return parent;
}
// DOM Level 1 solution, as fallback. Hugely expensive.
Element rootElem = doc.getDocumentElement();
if (null == rootElem)
{
throw new RuntimeException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT,
null)); //"Attribute child does not have an owner document element!");
}
parent = locateAttrParent(rootElem, node);
}
else
{
parent = node.getParentNode();
// if((Node.DOCUMENT_NODE != nodeType) && (null == parent))
// {
// throw new RuntimeException("Child does not have parent!");
// }
}
return parent;
}
boolean testImpl(DOMImplementation impl, String features) {
StringTokenizer st = new StringTokenizer(features);
String feature = null;
String version = null;
if (st.hasMoreTokens()) {
feature = st.nextToken();
}
while (feature != null) {
boolean isVersion = false;
if (st.hasMoreTokens()) {
char c;
version = st.nextToken();
c = version.charAt(0);
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
isVersion = true;
}
} else {
version = null;
}
if (isVersion) {
if (!impl.hasFeature(feature, version)) {
return false;
}
if (st.hasMoreTokens()) {
feature = st.nextToken();
} else {
feature = null;
}
} else {
if (!impl.hasFeature(feature, null)) {
return false;
}
feature = version;
}
}
return true;
}
/**
* Obtain the XPath-model parent of a DOM node -- ownerElement for Attrs,
* parent for other nodes.
* <p>
* Background: The DOM believes that you must be your Parent's
* Child, and thus Attrs don't have parents. XPath said that Attrs
* do have their owning Element as their parent. This function
* bridges the difference, either by using the DOM Level 2 ownerElement
* function or by using a "silly and expensive function" in Level 1
* DOMs.
* <p>
* (There's some discussion of future DOMs generalizing ownerElement
* into ownerNode and making it work on all types of nodes. This
* still wouldn't help the users of Level 1 or Level 2 DOMs)
* <p>
*
* @param node Node whose XPath parent we want to obtain
*
* @return the parent of the node, or the ownerElement if it's an
* Attr node, or null if the node is an orphan.
*
* @throws RuntimeException if the Document has no root element.
* This can't arise if the Document was created
* via the DOM Level 2 factory methods, but is possible if other
* mechanisms were used to obtain it
*/
public static Node getParentOfNode(Node node) throws RuntimeException
{
Node parent;
short nodeType = node.getNodeType();
if (Node.ATTRIBUTE_NODE == nodeType)
{
Document doc = node.getOwnerDocument();
/*
TBD:
if(null == doc)
{
throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT, null));//"Attribute child does not have an owner document!");
}
*/
// Given how expensive the tree walk may be, we should first ask
// whether this DOM can answer the question for us. The additional
// test does slow down Level 1 DOMs slightly. DOMHelper2, which
// is currently specialized for Xerces, assumes it can use the
// Level 2 solution. We might want to have an intermediate stage,
// which would assume DOM Level 2 but not assume Xerces.
//
// (Shouldn't have to check whether impl is null in a compliant DOM,
// but let's be paranoid for a moment...)
DOMImplementation impl=doc.getImplementation();
if(impl!=null && impl.hasFeature("Core","2.0"))
{
parent=((Attr)node).getOwnerElement();
return parent;
}
// DOM Level 1 solution, as fallback. Hugely expensive.
Element rootElem = doc.getDocumentElement();
if (null == rootElem)
{
throw new RuntimeException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT,
null)); //"Attribute child does not have an owner document element!");
}
parent = locateAttrParent(rootElem, node);
}
else
{
parent = node.getParentNode();
// if((Node.DOCUMENT_NODE != nodeType) && (null == parent))
// {
// throw new RuntimeException("Child does not have parent!");
// }
}
return parent;
}
/**
* Obtain the XPath-model parent of a DOM node -- ownerElement for Attrs,
* parent for other nodes.
* <p>
* Background: The DOM believes that you must be your Parent's
* Child, and thus Attrs don't have parents. XPath said that Attrs
* do have their owning Element as their parent. This function
* bridges the difference, either by using the DOM Level 2 ownerElement
* function or by using a "silly and expensive function" in Level 1
* DOMs.
* <p>
* (There's some discussion of future DOMs generalizing ownerElement
* into ownerNode and making it work on all types of nodes. This
* still wouldn't help the users of Level 1 or Level 2 DOMs)
* <p>
*
* @param node Node whose XPath parent we want to obtain
*
* @return the parent of the node, or the ownerElement if it's an
* Attr node, or null if the node is an orphan.
*
* @throws RuntimeException if the Document has no root element.
* This can't arise if the Document was created
* via the DOM Level 2 factory methods, but is possible if other
* mechanisms were used to obtain it
*/
public static Node getParentOfNode(Node node) throws RuntimeException
{
Node parent;
short nodeType = node.getNodeType();
if (Node.ATTRIBUTE_NODE == nodeType)
{
Document doc = node.getOwnerDocument();
/*
TBD:
if(null == doc)
{
throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT, null));//"Attribute child does not have an owner document!");
}
*/
// Given how expensive the tree walk may be, we should first ask
// whether this DOM can answer the question for us. The additional
// test does slow down Level 1 DOMs slightly. DOMHelper2, which
// is currently specialized for Xerces, assumes it can use the
// Level 2 solution. We might want to have an intermediate stage,
// which would assume DOM Level 2 but not assume Xerces.
//
// (Shouldn't have to check whether impl is null in a compliant DOM,
// but let's be paranoid for a moment...)
DOMImplementation impl=doc.getImplementation();
if(impl!=null && impl.hasFeature("Core","2.0"))
{
parent=((Attr)node).getOwnerElement();
return parent;
}
// DOM Level 1 solution, as fallback. Hugely expensive.
Element rootElem = doc.getDocumentElement();
if (null == rootElem)
{
throw new RuntimeException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT,
null)); //"Attribute child does not have an owner document element!");
}
parent = locateAttrParent(rootElem, node);
}
else
{
parent = node.getParentNode();
// if((Node.DOCUMENT_NODE != nodeType) && (null == parent))
// {
// throw new RuntimeException("Child does not have parent!");
// }
}
return parent;
}
boolean testImpl(DOMImplementation impl, String features) {
StringTokenizer st = new StringTokenizer(features);
String feature = null;
String version = null;
if (st.hasMoreTokens()) {
feature = st.nextToken();
}
while (feature != null) {
boolean isVersion = false;
if (st.hasMoreTokens()) {
char c;
version = st.nextToken();
c = version.charAt(0);
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
isVersion = true;
}
} else {
version = null;
}
if (isVersion) {
if (!impl.hasFeature(feature, version)) {
return false;
}
if (st.hasMoreTokens()) {
feature = st.nextToken();
} else {
feature = null;
}
} else {
if (!impl.hasFeature(feature, null)) {
return false;
}
feature = version;
}
}
return true;
}
/**
* Obtain the XPath-model parent of a DOM node -- ownerElement for Attrs,
* parent for other nodes.
* <p>
* Background: The DOM believes that you must be your Parent's
* Child, and thus Attrs don't have parents. XPath said that Attrs
* do have their owning Element as their parent. This function
* bridges the difference, either by using the DOM Level 2 ownerElement
* function or by using a "silly and expensive function" in Level 1
* DOMs.
* <p>
* (There's some discussion of future DOMs generalizing ownerElement
* into ownerNode and making it work on all types of nodes. This
* still wouldn't help the users of Level 1 or Level 2 DOMs)
* <p>
*
* @param node Node whose XPath parent we want to obtain
*
* @return the parent of the node, or the ownerElement if it's an
* Attr node, or null if the node is an orphan.
*
* @throws RuntimeException if the Document has no root element.
* This can't arise if the Document was created
* via the DOM Level 2 factory methods, but is possible if other
* mechanisms were used to obtain it
*/
public static Node getParentOfNode(Node node) throws RuntimeException
{
Node parent;
short nodeType = node.getNodeType();
if (Node.ATTRIBUTE_NODE == nodeType)
{
Document doc = node.getOwnerDocument();
/*
TBD:
if(null == doc)
{
throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT, null));//"Attribute child does not have an owner document!");
}
*/
// Given how expensive the tree walk may be, we should first ask
// whether this DOM can answer the question for us. The additional
// test does slow down Level 1 DOMs slightly. DOMHelper2, which
// is currently specialized for Xerces, assumes it can use the
// Level 2 solution. We might want to have an intermediate stage,
// which would assume DOM Level 2 but not assume Xerces.
//
// (Shouldn't have to check whether impl is null in a compliant DOM,
// but let's be paranoid for a moment...)
DOMImplementation impl=doc.getImplementation();
if(impl!=null && impl.hasFeature("Core","2.0"))
{
parent=((Attr)node).getOwnerElement();
return parent;
}
// DOM Level 1 solution, as fallback. Hugely expensive.
Element rootElem = doc.getDocumentElement();
if (null == rootElem)
{
throw new RuntimeException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT,
null)); //"Attribute child does not have an owner document element!");
}
parent = locateAttrParent(rootElem, node);
}
else
{
parent = node.getParentNode();
// if((Node.DOCUMENT_NODE != nodeType) && (null == parent))
// {
// throw new RuntimeException("Child does not have parent!");
// }
}
return parent;
}
/**
* Obtain the XPath-model parent of a DOM node -- ownerElement for Attrs,
* parent for other nodes.
* <p>
* Background: The DOM believes that you must be your Parent's
* Child, and thus Attrs don't have parents. XPath said that Attrs
* do have their owning Element as their parent. This function
* bridges the difference, either by using the DOM Level 2 ownerElement
* function or by using a "silly and expensive function" in Level 1
* DOMs.
* <p>
* (There's some discussion of future DOMs generalizing ownerElement
* into ownerNode and making it work on all types of nodes. This
* still wouldn't help the users of Level 1 or Level 2 DOMs)
* <p>
*
* @param node Node whose XPath parent we want to obtain
*
* @return the parent of the node, or the ownerElement if it's an
* Attr node, or null if the node is an orphan.
*
* @throws RuntimeException if the Document has no root element.
* This can't arise if the Document was created
* via the DOM Level 2 factory methods, but is possible if other
* mechanisms were used to obtain it
*/
public static Node getParentOfNode(Node node) throws RuntimeException
{
Node parent;
short nodeType = node.getNodeType();
if (Node.ATTRIBUTE_NODE == nodeType)
{
Document doc = node.getOwnerDocument();
/*
TBD:
if(null == doc)
{
throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT, null));//"Attribute child does not have an owner document!");
}
*/
// Given how expensive the tree walk may be, we should first ask
// whether this DOM can answer the question for us. The additional
// test does slow down Level 1 DOMs slightly. DOMHelper2, which
// is currently specialized for Xerces, assumes it can use the
// Level 2 solution. We might want to have an intermediate stage,
// which would assume DOM Level 2 but not assume Xerces.
//
// (Shouldn't have to check whether impl is null in a compliant DOM,
// but let's be paranoid for a moment...)
DOMImplementation impl=doc.getImplementation();
if(impl!=null && impl.hasFeature("Core","2.0"))
{
parent=((Attr)node).getOwnerElement();
return parent;
}
// DOM Level 1 solution, as fallback. Hugely expensive.
Element rootElem = doc.getDocumentElement();
if (null == rootElem)
{
throw new RuntimeException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT,
null)); //"Attribute child does not have an owner document element!");
}
parent = locateAttrParent(rootElem, node);
}
else
{
parent = node.getParentNode();
// if((Node.DOCUMENT_NODE != nodeType) && (null == parent))
// {
// throw new RuntimeException("Child does not have parent!");
// }
}
return parent;
}