1

我有以下xml

<customers>
   <continent>NA</continent>
   <Type>Regular<Type>
   <customer>
      <name>John Smith</name>
      <address>123 Oak St.</address>
      <state>WA</state>
      <phone>(206) 123-4567</phone>
   </customer>
   <customer>
      <name>Zack Zwyker</name>
      <address>368 Elm St.</address>
      <state>WA</state>
      <phone>(206) 423-4537</phone>
   </customer>
<customers>

我正在尝试为每个客户构建一个地图对象,如下所示:

for $customer in //customers
return 
map {
'continent': //continent/string(),
'type': //Type/string(),
'name': $customer/name/string(),
'address': $customer/address/string(),
'state': $customer/state/string(),
'phone': $customer/phone/string()
}

但是对于每次迭代,我都使用相同的大陆和类型,每个客户都使用相同的类型。

我如何构建我的 xpath,以便只生成一次大陆和类型元素,并且可以在每个地图中访问。

4

2 回答 2

1

我想你打算for $customer in //customer(不是//customers)。

Saxon-EE 优化器将自动拉出表达式//continent/string()//Type/string()退出“for”循环,但如果您想手动进行此优化,您可以编写:

let $continent := //continent/string(), $type := //Type/string()
return
  for $customer in //customers
  return 
    map {
     'continent': $continent,
     'type': $type,
     'name': $customer/name/string(),
     'address': $customer/address/string(),
     'state': $customer/state/string(),
     'phone': $customer/phone/string()
   }

或者,我可能会在没有任何变量的情况下将其编写为

(//customer) !
    map {
     'continent': string(..!continent),
     'type': string(..!type),
     'name': string(name),
     'address': string(address),
     'state': string(state),
     'phone': string(phone)
   }
于 2018-06-18T09:14:07.157 回答
0

但是对于每次迭代,我都使用相同的大陆和类型,每个客户都使用相同的类型。

我如何构建我的 xpath,以便只生成一次大陆和类型元素,并且可以在每个地图中访问。

我将首先创建另一个map并将其分配给一个变量

let $common := map
{
 'continent' : /customers/continent/string(.),
 'type' : /customers/Type/string(.)
}
 return
  for $customer in /customers/customer
  return 
    map {
     'continent': $common?continent,
     'type': $common?type,
     'name': $customer/name/string(),
     'address': $customer/address/string(),
     'state': $customer/state/string(),
     'phone': $customer/phone/string()
   } 

或者甚至可以只存储$common在每个地图中——这意味着无论何时continenttype需要任何地图(假设包含在一个变量中$theMap),这些都将被访问为:

$theMap?common?continent

$theMap?common?type

如果您更喜欢这种设计,那么生成地图的代码将是

let $common := map
{
 'continent' : /customers/continent/string(.),
 'type' : /customers/Type/string(.)
}
 return
  for $customer in /customers/customer
  return 
    map {
     'common': $common,
     'name': $customer/name/string(),
     'address': $customer/address/string(),
     'state': $customer/state/string(),
     'phone': $customer/phone/string()
   } 
于 2019-12-21T03:49:18.760 回答