JAXB绑定文件:名称空间感知节点选择

时间:2011-04-12 11:27:53

标签: xpath xsd jaxb xml-namespaces

我倾向于使用外部JAXB绑定文件进行Schema-to-Java编译。这很好用,但我确实注意到了一件我开始想知道的事情。它不是特定于JAXB的,更像是一个XPath问题,但上下文有帮助。

假设我们有这个架构:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:test="www.acme.com"
 targetNamespace="www.acme.com"
 elementFormDefault="qualified" attributeFormDefault="unqualified">

  <xs:element name="el1"/>

  <xs:complexType name="testType">
    <xs:sequence>
      <xs:element ref="test:el1"/>
    </xs:sequence>
  </xs:complexType>

</xs:schema>

复杂类型中的元素引用需要前缀“test”,绑定到目标名称空间,以查找元素定义。如果我们省略了前缀,架构处理器会抱怨它无法找到它引用的元素。很明显,引用是一个限定名称,架构处理器也知道这一点。

现在为XJC采取以下绑定文件提取

<bindings node="//xs:complexType[@name='testType']">
  <bindings node=".//xs:element[@ref='test:el1']">
    <property name="element1"/>
  </bindings>
</bindings>

复杂类型的绑定很清楚。我们按名称选择它,xs前缀绑定在绑定文件的根目录中(此处未显示)。它可能也是xsd 我的错误是嵌套绑定。在我们的复杂类型节点的上下文中,我们选择xs:element节点,其属性ref具有值test:el1。但这个价值仅仅被视为文本。 XML处理器不知道它应该是一个限定名称,而test:实际上是绑定到命名空间的前缀声明。

现在我知道我在挑剔,但实际的前缀字符串应该没有重要性,只有命名空间URI本身。有人可以将架构中的test前缀更改为acme,并且它在语义上仍然是相同的架构。但是,我的绑定文件将不再有效。

那么,有没有办法构建XPath表达式而不依赖于前缀的知识,只有命名空间URI?这显然不是一个大问题,但我对此感到好奇。

1 个答案:

答案 0 :(得分:4)

  

有没有办法构建   不依赖于XPath表达式   知道前缀,只有   名称空间URI?

如果你谈论一个属性值,那就是XPath 1.0

.//xs:element[
   namespace::*[
      . = 'www.acme.com'
   ][
      susbtring-before(
         ../@ref,
         ':'
      )
    = name()
   ]
 and
   substring(
      concat(':', @ref),
      string-length(@ref) - 1
   )
 = 'el1'
]

在XPath 2.0中更简单:

.//xs:element[resolve-QName(@ref,.) eq QName('www.acme.com','el1')]