我倾向于使用外部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?这显然不是一个大问题,但我对此感到好奇。
答案 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')]