Search code examples
javaxmlxsltxsdxmlbeans

XMLBeans - Handle the namespace


I complete the xmlbean tutorial with XML file and XSD file and successfully access all data.

Now i add the namespace for XML and XSD file recompile and recreate the jar file. After this the package name change in the java file but here i am facing issue as i am getting the null for each xsd parameter.Following is XSD file

<?xml version="1.0" encoding="UTF-8"?>
   <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="serverDetail">
<xsd:element name="ServerConfig">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:element name="driverClassName" type="xsd:string"/>
            <xsd:element name="url" type="xsd:string"/>
            <xsd:element name="user" type="xsd:string"/>
            <xsd:element name="password" type="xsd:string"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>

Following is xml file

<?xml version="1.0" encoding="UTF-8"?>
<!-- Contains server details-->
<ServerConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="serverDetail" xsi:SchemaLocation="serverConfig.xsd">
       <driverClassName>com.mysql.jdbc.Driver</driverClassName>
       <url>jdbc:mysql://localhost:3306/test</url>
       <user>root</user>
       <password>root</password>
</ServerConfig>

Following is java class files

     import serverDetail.ServerConfigDocument;
     import org.apache.xmlbeans.*;

     String filePath = "E:/Gradle/DemoTest/src/serverConfig.xml";
     java.io.File inputXMLFile = new java.io.File(filePath);
     try {
        ServerConfigDocument serverDoc= ServerConfigDocument.Factory.parse(inputXMLFile);
        ServerConfigDocument.ServerConfig serverConfig=serverDoc.getServerConfig();
        System.out.println("Server details\nDriverClassName " + serverConfig.getDriverClassName());
        System.out.println("Url is " + serverConfig.getUrl());
        System.out.println("User is " + serverConfig.getUser());
        System.out.println("Password is " + serverConfig.getPassword());
    } catch (XmlException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

So here i am getting the output as null.

 Server details
 DriverClassName null
 Url is null
 User is null
 Password is null

Can anyone help me here..


Solution

  • Short answer: add elementFormDefault="qualified" to the xsd:schema element.

    As currently written, your schema declares a top-level ServerConfig element in the schema's targetNamespace, but "local" element declarations inside the complexType do not take on the targetNamespace, so XMLBeans is expecting an XML document that looks like

    <ns:ServerConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xmlns:ns="serverDetail"
                     xsi:schemaLocation="serverDetail serverConfig.xsd">
       <driverClassName>com.mysql.jdbc.Driver</driverClassName>
       <url>jdbc:mysql://localhost:3306/test</url>
       <user>root</user>
       <password>root</password>
    </ns:ServerConfig>
    

    You haven't provided any driverClassName, url, etc. elements without a namespace, so XMLBeans correctly gives null for the corresponding properties.

    If you want local elements to be in the targetNamespace as well, then you need to add elementFormDefault="qualified" to the schema

       <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   targetNamespace="serverDetail"
                   elementFormDefault="qualified">
    

    with this in place the following would validate successfully

    <ServerConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns="serverDetail"
                  xsi:schemaLocation="serverDetail serverConfig.xsd">
       <driverClassName>com.mysql.jdbc.Driver</driverClassName>
       <url>jdbc:mysql://localhost:3306/test</url>
       <user>root</user>
       <password>root</password>
    </ServerConfig>
    

    P.S. namespace identifiers should normally be URIs, so instead of serverDetail you should use something like urn:serverDetail or a fake http:// URL of some kind.