如何获得" Type"一个DOM元素?

时间:2017-06-16 11:32:55

标签: java xml dom xsd xml-namespaces

我想使用Java的org.w3c.dom来访问DOM元素的xsi:type(不是jaxb或guava或apache.commons等)。

我有一个XML,其中一个元素有几种可能的类型,基类型是抽象的 - 像这样:

<xsd:complexType name="AbstractBaseType" abstract="true"/>

<xsd:element name="Derived" type="message:DerivedType1"/>
<xsd:complexType name="DerivedType1">
    <xsd:complexContent>
        <xsd:extension base="message:AbstractBaseType">
...

在具体的XML中,这看起来像这样:

<ns4:root xmlns:ns="..." ...>
  <element xsi:type="ns3:DerivedType1" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    ...

现在,<element>可以是从AbstractBaseType派生的任何类型,在这种情况下,它是DerivedType1类型中注明的类型xsi:type。我假设XML或XSD标准定义了它的工作原理。

我已成功导航<root><element>,如下所示:

Document doc = parseToDocument("<ns4:root...");
Element documentElement = doc.getDocumentElement()
Element child = (Element)findChild(documentElement, "element", true, 5);
// now 'child' is the '<element>'-node
// - but how do I get 'DerivedType1'?
Attr type = child.getAttributeNodeNS("http://www.w3.org/2001/XMLSchema-instance", "type");
String typeName = type.getValue();

现在typeName包含"ns3:DerivedType1"

有没有办法在没有"DerivedType1" (和类似)的情况下前往typename.split(":")

辅助方法

private Document parseToDocument(String data) throws ParserConfigurationException, SAXException, IOException {
  DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
  domFactory.setNamespaceAware(true); // important!
  DocumentBuilder builder = domFactory.newDocumentBuilder();
  ByteArrayInputStream bis = new ByteArrayInputStream(data.getBytes("UTF8"));
  return builder.parse(bis);
}

/** breadth first */
private Node findChild(Node node, final String localName, boolean checkNode, final int limitDepth) {
  if(node==null) return null;
  if(limitDepth < 0) return null;
  if(checkNode && StringUtils.equals(node.getLocalName(), localName)) return node;
  final NodeList childNodes = node.getChildNodes();
  if(childNodes == null) return null;
  for(int i=0; i < childNodes.getLength(); ++i) {
    final Node child = childNodes.item(i);
    if(StringUtils.equals(child.getLocalName(), localName)) return child;
  }
  final int limitDepthNew = limitDepth - 1;
  for(int i=0; i < childNodes.getLength(); ++i) {
    final Node result = findChild(childNodes.item(i), localName, false, limitDepthNew);
    if(result != null) return result;
  }
  return null;
}

0 个答案:

没有答案