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.

+3


source to share


2 answers


"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

    for jaxb2-marshaller

    that is defined spring-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 each spring-xxx.jar

    , you will find the file spring.schemas

    and spring.handlers

    . There you will find

    http\://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 find

    registerBeanDefinitionParser("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 method doParse()

    - 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.

+2


source


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.
+1


source







All Articles