【问题标题】:XML Schema. Processing namespace-aware attribute valuesXML 架构。处理命名空间感知的属性值
【发布时间】:2026-01-13 22:35:02
【问题描述】:

我的部分项目涉及对用户定义的架构文档进行大量转换。我需要能够更改目标命名空间、支持类型交叉引用并在多个模式文档上构建wsdl。 最常用的操作之一是在将模式导入 wsdl 文件之前更改名称空间前缀。我正在使用org.xml.sax.ContentHandler,它是startPrefixMapping 处理命名空间的方法。除非我想更改元素类型,否则一切正常且完美无缺。

这是简单的模式片段

<schema xmlns="http://www.w3.org/2001/XMLSchema">
  <complexType name="Param">
    <sequence>
      <element name="key" type="string"/>
      <element name="value" type="string"/>
    </sequence>
  </complexType>
<!-- omitted -->

必须放在wsdl里面,如下:

<definitions xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <types>
    <xs:schema>
      <xs:complexType name="Param">
        <xs:sequence>
          <xs:element name="key" type="xs:string"/> <!-- 'xs:' to be added -->
          <xs:element name="value" type="xs:string"/> <!-- 'xs:' to be added -->
        </xs:sequence>
      </xs:complexType>
<!-- omitted -->

问题在于某些模式的属性值(&lt;element&gt; 中的type&lt;extension&gt; 中的base)是命名空间感知的,并且在上面的示例中可能会发生变化。如我所见,DOM 和 SAX 解析器都无法处理这种情况,因此我目前正在使用丑陋的字符串操作从特定属性值中检索命名空间信息。

我错过了什么吗?是否有任何 API、库或其他特定于模式的工具来处理此类任务?

【问题讨论】:

  • 这有点麻烦……就元素或属性而言,前缀不是限定名称的一部分,而是字符数据的一部分。解析器本质上不会意识到这一点。我曾经问过一个reminds me of your problem 的问题。也许您可以通过 XSLT 样式表传递 XML,当遇到属于模式命名空间的元素时,该样式表处理某些属性的内容(如 type)。
  • @G_H,感谢您的评论。使用 XSLT 似乎是可以接受的解决方案,尤其是在阅读了 jtahlborn 对此主题的看法之后。

标签: java xml xsd xml-parsing


【解决方案1】:

SAX 是一个非常低的级别,用于读取模式文档。如果您迁移到 XSLT 等更高级别的界面,您将消除很多麻烦。如果您使用将模式处理器转换为模式组件模型的模式处理器来读取模式文档,您将消除更多麻烦 - Xerces 和 Saxon 都可以做到这一点,而且他们并不孤单。

【讨论】:

    【解决方案2】:

    是的,这是 xml schema/wsdl 中的一个主要错误。在属性值中使用 xml 命名空间前缀是一个巨大的错误(因为前缀值本身并不重要,只有实际命名空间的占位符)。不幸的是,我不知道有什么好的解决方案(我不得不实现几乎相同的想法:将多个用户定义的模式合并到一个模式/wsdl)。我知道 xerces 有一个xml schema model api,但我不知道它是否支持将多个模式合并在一起并生成结果输出。

    【讨论】: