XML 命名空间在没有有效网络连接的情况下如何工作?

Posted

技术标签:

【中文标题】XML 命名空间在没有有效网络连接的情况下如何工作?【英文标题】:How do XML namespaces work without a working network connection? 【发布时间】:2012-02-10 09:41:36 【问题描述】:
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"

       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.1.xsd">

  <context:component-scan
      base-package="com.springinaction.chapter01.knight" />

</beans>

上面的例子显示了一个带有多个命名空间的 XML 文件的例子。这些命名空间的目的是什么?最重要的是,为什么它们即使在没有 Internet 连接的情况下也能工作?

我认为以xsi:schemaLocation 开头的第二位包含用于验证 XML 文档结构的 XML 模式文件。如果我在不在网络上的机器上运行使用此配置文件的应用程序,这些为什么仍然有效?这些 URL 是否是 JAR 文件的别名?

【问题讨论】:

【参考方案1】:

假设我们有这个 XML 文档。

<?xml version="1.0" encoding="UTF-8"?>
<html>
      <body>
        Your text here
      </body>
      <body>
        <height>182 cm</height>
        <weight>83 kg</weight>
      </body>
</html>

它包括 HTML,它有一个带有 HTML 渲染器语义含义的 body 标签。它还有另一个身体标签,其中包含有关特定人的信息。命名空间定义了这个标签的语义范围。如果没有命名空间(如提供的示例中所示),解析器就不可能区分它们,因为它们在语法上是相同的。

这是同一文档的语义正确版本:

<?xml version="1.0" encoding="UTF-8"?>
<html:html xmlns:html="http://www.w3.org/TR/xhtml1/">
  <html:body>
    Your text here
  </html:body>
  <human:body xmlns:human="http://www.example.com/human/">
    <human:height>182 cm</human:height>
    <human:weight>83 kg</human:weight>
  </human:body>
</html:html>

因此,多亏了命名空间,我们不必担心具有不同含义的标签冲突。

命名空间 URI 本身从未真正解析过,并且是任意的(因此您可以离线使用它们)。

【讨论】:

为什么我们只需要使用 url 为什么不使用一些独特的词来分隔命名空间中的这些标签。谢谢 某些语言(如 WPF 和 xaml)使用命名空间,如 using 语句。发生这种情况时,网址很重要。 @Mitch 我认为犯了一个错误。应该是:example.com/human">【参考方案2】:

命名空间通常是为了避免标签之间的冲突,但在幕后它是解析器针对某些模式的处理指令。例如,在浏览器中,您有不同的文档类型、严格的 Xhtml 等,浏览器将这些架构存储在某个地方,解析器会引用这些架构来验证结构。

在 Spring 中,一旦你启用了一个特定的模式,它就需要一个引用该模式所在的位置,这并不意味着 URI 模式没有意义。类路径中将需要相关的 .jar 文件,以便解析器引用它。 org.springframework.context-4.1.jar。如果你查看这个 jar 文件,你会在包 org.springframework.context.config 中找到 spring-context-2.5.xsd 文件。 你定义: xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/context/spring-context-2.5.xsd">

xmlns 让您通过您的编辑器使用预配置的方式来编写例如来自xmlns:context&lt;context tag,并启用经过验证的标签,例如:

 <context:annotation-config> 

在 TURN 中激活要在 bean 类中检测的各种注释: @Required @Autowired、@PostConstruct、@PreDestroy 和 @Resource 等等。

所以实际上解析器会在解析 Bean 时找到意义。

架构非常需要,至少必须下载一次,您的 IDE 或应用程序将用于验证,否则将创建验证异常。如果它在这些 jar 中本地可用,则它不会寻找下载。

【讨论】:

【参考方案3】:

XML 命名空间是元素名称的组成部分,您可以在编写xmlns:&lt;prefix&gt;="&lt;namespace&gt;" 时将其绑定到前缀。这有助于避免不同 XML 模式之间的命名冲突,以便您可以混合来自碰巧具有相同名称的两个模式的元素。例如,您可能有两个模式,它们都具有具有不同含义的link 元素,并且命名空间前缀让您可以通过编写foo:linkbar:link 来区分它们。命名空间通常采用 URL 的形式,但解析器只是将其视为字符串,不会尝试从该 URL 获取任何内容。

您对第二部分XSI:SchemaLocation 元素是正确的。请参阅 this answer 了解为什么它仍然能够在没有网络连接的情况下验证架构。

【讨论】:

XML 命名空间不是前缀,因此对其进行描述只会造成混淆。命名空间是通常看起来像 URL 的字符串。前缀可以用于将元素绑定到其命名空间。 @Alohci 感谢您指出这一点,我并不是说前缀是命名空间。我已经编辑了我的答案以区分两者。【参考方案4】:

尽量忽略许多命名空间名称看起来像您可能在浏览器中键入的 URL 的事实。它们只是随机的字符串,它们不是网络上的资源地址。人们采用此约定的原因是它显示了谁“拥有”该名称 - http://www.w3.org/2001/XMLSchema 所指的内容比他们选择“xsd1.0”作为命名空间名称更清楚,并且不太可能与名称发生意外冲突由别人选择。有些人还喜欢您可以将文档放在相关位置,但没有 XML 软件会自动查找文档。

【讨论】:

很好,谢谢。如果我错过了 bean 类标记,我怀疑当我在 java 中使用 beans 命名空间时,ecllipse 会显示一个错误,就像你错过的那样。该名称空间将如何在不解析的情况下工作。请原谅我的英语不好。

以上是关于XML 命名空间在没有有效网络连接的情况下如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有 xmlns="..." 的情况下使用 XML 命名空间前缀? (。网)

如何在具有默认命名空间的 xml 文档上使用 XPath

如何在没有 Composer 作为依赖项(PSR-0)的情况下使用具有命名空间的 PHP 库?

重命名元素的 XSLT 问题——更改命名空间

默认情况下声明了哪些 XML 命名空间?

『XML』XML/XSD命名空间解析