XML namespace for elements that can be added to an XML document?
I have this doubt about the namespace in XML. Consider the xml namespace I have in my spring application:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
xmlns:context="http://www.springframework.org/schema/context">
Is this server only targeted as a namespace (a way to avoid name collision) OR what elements can be added to the xml document?
I was adding item config (hibernate / spring) and it was complaining that we need to add some namespace? If the namespace serves only as a way to avoid name collisions (XSD advises that all elements can be contained and XML document). I was wondering if adding a namespace that spring expects (basically any XML parser) will be able to get the element. Isn't it an XSD problem that says all elements can be contained in an XML document?
I have this doubt, any clarification would be helpful.
I did google to get my answer however not satisfied as I could not clear up the doubt.
source to share
"Is this server only targeted as a namespace (a way to avoid name collisions) OR what elements can be added to the XML document?"
Last.
Namesapces are used to define elements and attributes in a schema definition.
"I was adding item config (hibernate / spring) and it complained that we need to add some namespace?"
When doing persistence with Spring, you'll usually need a spring-orm
jar spring-jdbc
, spring-tx
and perhaps a few others along with it. Typically, all banks spring-xxx
have their own schema definitions. As stated above, if you want to use an element in this particular schema, you need to add the namespace to the context file.
Existing namespaces are just namespaces beans
and context
. If you look at the xsds, you can see all the top level elements allowed for these namespaces. For example, the namespace allows only beans <alias>
, <bean>
, <beans>
, <description>
and <import>
. And the context namespace only supports
<context:annotation-config>
<context:component-scan>
<context:load-time-weaver>
<context:mbean-export>
<context:mbean-server>
<context:property-override>
<context:property-placeholder>
<context:spring-configured>
Since beans is the default namespace for the document
<beans xmlns="http://www.springframework.org/schema/beans"
you don't need to prefix elements (for example <beans:bean>
) like with<context:component-scan>
Regarding your current problem, "she was complaining that we need to add some namespace" ... You didn't actually provide enough information to help you sort out the problem, but usually when doing persistence, you will need a tx
namespace to handle transactions , and if you want to use the built-in database, you might need the jdbc namespace with an element <jdbc:embedded-database>
.
This is just general guesswork.
"I was wondering if adding a namespace that spring expects (essentially any xml parser) will be able to get an element. Isn't that an XSD problem that says all elements can be contained in an XML document?"
A bit unclear about your misunderstanding, but like any other schema based xml it should check. The schema is similar to class definition. A class definition is a contract for what is allowed for instances of that class.
Spring, uses your context to create all the beans that you define. If they are not defined correctly, spring may not know what to do with your xml. That's why we have schematics - to follow its guidelines, for a higher-level application, you need to follow in order to work.
What spring is doing under the hood is taking your XML file and using the appropriate one NamespaceHandler
, able to find the right parser. And the parser's job is to create bean definitions that allow the spring container to instantiate beans
Example stream:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="http://www.springframework.org/schema/oxm
http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<oxm:jaxb2-marshaller>
<oxm:class-to-be-bound name="com.underdogdevs.spring.oxm.Application" />
</oxm:jaxb2-marshaller>
</beans>
-
Using a namespace
oxm
forjaxb2-marshaller
that is definedspring-oxm-4.0.xsd
in one of the jars. -
Pay attention to
schemaLocation http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd
. spring will use this to define the handler. -
Take a look
META-INF
which is included in eachspring-xxx.jar
, you will find the filespring.schemas
andspring.handlers
. There you will findhttp\://www.springframework.org/schema/oxm/ spring-oxm-4.0.xsd=org/springframework/oxm/config/spring-oxm-4.0.xsd http\://www.springframework.org/schema /oxm=org.springframework.oxm.config.OxmNamespaceHandler
this tells spring which schema to check and what the namespace handler being used is
OxmNamespaceHandler
, respectively. -
If we look at the class
OxmNamespaceHandler
, you will findregisterBeanDefinitionParser("jaxb2-marshaller", new Jaxb2MarshallerBeanDefinitionParser());
What happens is now the namespace handler directs us to the correct parser.
-
Now review
Jaxb2MarshallerBeanDefinitionParser
@Override protected String getBeanClassName(Element element) { return "org.springframework.oxm.jaxb.Jaxb2Marshaller"; } @Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder beanDefinitionBuilder) { String contextPath = element.getAttribute("context-path"); if (!StringUtils.hasText(contextPath)) { // Backwards compatibility with 3.x version of the xsd contextPath = element.getAttribute("contextPath"); } if (StringUtils.hasText(contextPath)) { beanDefinitionBuilder.addPropertyValue("contextPath", contextPath); } List<Element> classes = DomUtils.getChildElementsByTagName(element, "class-to-be-bound"); if (!classes.isEmpty()) { ManagedList<String> classesToBeBound = new ManagedList<String>(classes.size()); for (Element classToBeBound : classes) { String className = classToBeBound.getAttribute("name"); classesToBeBound.add(className); } beanDefinitionBuilder.addPropertyValue("classesToBeBound", classesToBeBound); } }
The interesting point is the method
getBeanClassName
that returns"org.springframework.oxm.jaxb.Jaxb2Marshaller"
. This is how spring knows which bean to create. Also, if you look at the context file above, you will see an element<oxm:class-to-be-bound>
. This is part of the schema definition for the item<oxm:jax2b-marshaller>
. You can also see it in the methoddoParse()
-getChildElementsByTagName(element, "class-to-be-bound");
.
All this to make sure we get a good copy Jaxb2marshaller
at the end. It works pretty much the same way as everything in Spring.
So you can see how much is going on behind the scenes with Spring, and hopefully you can understand why namespaces are needed.
source to share
You are correct that the purpose of namespaces is to avoid name collisions.
What you are missing is that when used, the namespace becomes part of the name. Yes, it is the XSD's job to "tell that all elements can be contained in an XML document." Part of this job is managing the names, and the namespaces are an integral part of the element or attribute name.
Update for OP's questions in the following comment ...
Setting a namespace relationship between XSD and XML
The Basics of Using XML Schema to Define Elements will be helpful . Pay particular attention to the points that
-
xsd:schema/@targetNamespace
works on the XSD side to declare the namespace that it defines. -
@xsi:schemaLocation
runs on the side of the XML document instance . for a hint on how to find the XSD for each of the namespaces in the game.
source to share