有关可以添加到XML文档的元素的XML命名空间信息?

时间:2014-09-19 08:17:36

标签: xml spring xml-parsing xsd

我对XML中的命名空间有疑问。考虑我在spring应用程序中使用的xml命名空间:

<?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">

此服务器是否仅用作命名空间(避免命名冲突的方式)或者可以将哪些元素添加到xml文档中?

我正在添加元素(hibernate / spring配置),它抱怨我们需要添加一些命名空间?如果命名空间仅用作避免命名冲突的方法(XSD告诉所有元素可以包含在xml文档中)。我有这样的疑问,如何添加一个命名空间,Spring希望(对于任何xml解析器)能够获得该元素。不是XSD的工作,它告诉XML文档中可以包含所有元素吗?

我有这个疑问,任何澄清都会有所帮助。

我确实谷歌得到了答案,但不满意因为无法清除疑问。

2 个答案:

答案 0 :(得分:2)

  

“此服务器是否仅用作命名空间(避免命名冲突的方式)或者可以将哪些元素添加到xml文档中?”

后者。

Namesapces用于标识模式定义中的元素和属性。

  

“我正在添加元素(hibernate / spring配置),它抱怨我们需要添加一些命名空间?”

使用Spring进行持久化,通常需要spring-orm jar,spring-jdbcspring-tx,以及可能还需要其他几个。通常,所有spring-xxx罐都带有其架构定义。如上所述,如果要在该特定模式中使用元素,则需要在上下文文件中添加名称空间。

您拥有的当前名称空间只是beanscontext名称空间。如果你看一下xsds,你会看到这些命名空间允许的所有顶级元素。例如,beans命名空间只允许<alias><bean><beans><description><import>。上下文命名空间仅支持

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

由于bean是文档的默认命名空间

<beans xmlns="http://www.springframework.org/schema/beans"

您不需要像<beans:bean>

那样为元素添加前缀(例如<context:component-scan>

至于你当前的问题“它抱怨我们需要添加一些命名空间” ...你实际上没有提供足够的信息来帮助你调查问题,但通常在做的时候持久性,您需要tx命名空间来处理事务,如果您想使用嵌入式数据库,您可能需要带有<jdbc:embedded-database>元素的jdbc命名空间。

这只是一般的猜测工作。

  

“我有这样的疑问,如何添加一个命名空间,Spring希望(对于任何xml解析器)能够获得该元素。是不是XSD的工作告诉所有元素可以包含在一个XML文档?“

有点不清楚你的误解,但就像任何其他基于模式的xml一样,它需要验证。模式就像一个类定义。类定义是该类实例允许的内容的契约。

Spring,使用您的上下文创建您定义的所有bean。如果定义不正确,Spring可能不知道如何处理你的xml。这就是为什么我们拥有模式 - 遵循他的指导原则,更高级别的应用程序需要您遵循才能工作。

Spring所做的是获取你的xml文件,并使用相应的NamespaceHandler,它能够找到你需要的解析器。解析器的工作是创建允许Spring容器实例化bean的bean定义

示例流程

<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>
  • oxm使用jaxb2-marshaller命名空间,spring-oxm-4.0.xsd在其中一个jar包中的schemaLocation http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd中定义。

  • 请注意META-INF。 Spring将使用它来确定处理程序。

  • 查看每个spring-xxx.jar中包含的spring.schemas,您会找到spring.handlershttp\://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 文件。在那里你会找到

    OxmNamespaceHandler

    这告诉spring要验证哪个架构,并且要使用的命名空间处理程序分别是OxmNamespaceHandler

  • 如果我们查看registerBeanDefinitionParser("jaxb2-marshaller", new Jaxb2MarshallerBeanDefinitionParser()); 课程,您会找到

    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); } }

    getBeanClassName

    需要注意的有趣点是返回"org.springframework.oxm.jaxb.Jaxb2Marshaller"的{​​{1}}方法。这就是Spring知道要创建哪个bean的方式。另外,如果查看上面的上下文文件,您将看到元素<oxm:class-to-be-bound>。这是<oxm:jax2b-marshaller>元素的模式定义的一部分。您也可以在doParse()方法 - getChildElementsByTagName(element, "class-to-be-bound");中看到它。

这一切都是为了确保我们最终获得Jaxb2marshaller的良好实例。对于Spring中的所有内容,它的工作方式几乎相同

所以你可以看到Spring的幕后工作有很多,希望你能看到为什么需要名称空间。

答案 1 :(得分:1)

你是对的,命名空间的目的是避免命名冲突。

您缺少的是,使用时,命名空间成为名称的一部分。是的,XSD的工作是“告诉所有元素可以包含在XML文档中”。部分工作是管理名称,名称空间是元素或属性名称的组成部分。


在以下评论中更新每个OP的问题......

指定XSD和XML之间的名称空间关系

您将受益于The basics of using XML Schema to define elements

要特别注意
  • xsd:schema/@targetNamespace在XSD端工作进行声明 它管辖的命名空间。
  • @xsi:schemaLocation在XML文档实例端上工作 提示如何为游戏中的每个命名空间找到XSD。