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

Xpath JAXB绑定文件:名称空间感知节点选择,xpath,xsd,jaxb,xml-namespaces,Xpath,Xsd,Jaxb,Xml Namespaces,我倾向于使用外部JAXB绑定文件进行模式到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

我倾向于使用外部JAXB绑定文件进行模式到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获取以下绑定文件extract

<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
,它在语义上仍然是相同的模式。但是,我的绑定文件将不再工作

那么,是否有任何方法可以在不依赖前缀(仅命名空间URI)知识的情况下构造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')]

那真是太棒了!我假设XJC处理器使用XSLT1.0,所以我将不使用XPath2函数。第一种语法有点过于冗长,无法在整个绑定文件中使用。但很高兴看到这真的是可能的。谢谢