当master和detail是XML中的单独数据集时,XML Master / detail数据选择

时间:2017-11-23 13:12:01

标签: xml xpath master-detail msxml selectnodes

请假设以下实际的XML结构(不,我们无法更改它)。

<root>
  <master>
    <record>
      <ID>1</ID>
      <Value>One</Value>
    </record>
    <record>
      <ID>2</ID>
      <Value>Two</Value>
    </record>
  </master>
  <detail>
    <record>
      <ID>A</ID>
      <MasterID>1</MasterID>
      <Value>Somevalue a</Value>
    </record>
    <record>
      <ID>B</ID>
      <MasterID>2</MasterID>
      <Value>Somevalue b</Value>
    </record>
    <record>
      <ID>C</ID>
      <MasterID>1</MasterID>
      <Value>Somevalue c</Value>
    </record>
    <record>
      <ID>D</ID>
      <Value>Somevalue d</Value>
    </record>
  </detail>
</root>

首先,我们对XML执行XPath查询,以返回可能的详细记录列表:

detailnodes = doc.documentElement.getElementsByTagName('/root/detail')

然后我们处理返回XML节点列表中的每个返回的detailrecord,此时我们只需要使用XPath表达式在detailnode中基于MasterID的主记录值。 我们不想使用应用程序代码来检索当前记录的MasterID,然后根据检索到的值创建XPath表达式

示例(不是这样)

for each detailnode in detailnodes do
  masterID = detailnode.ChildNodes['MasterID'].value
  masterValue = detailnode.selectNodes('../master[ID=" + MasterID + "]/Value')[0].value
end

示例(首选方式)

for each detailnode in detailnodes do
  masterValue = detailnode.selectNodes('../master[ID=?MasterID?]/Value')[0].value
end

XPath中的?MasterID?表达式应该返回当前detailnode的MasterID值。

这是否可以使用纯XPath表达式......?

修改 注意:我需要使用MSXML DOM ...

3 个答案:

答案 0 :(得分:0)

是的,您应该能够使用current()在Xml文档的其他位置查找值,这些值由当前作用域中的数据键入。另请注意,Xml索引是基于1的,因此您需要使用 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "UserCell", for: indexPath) as! UserProfileTableViewCell // Configure the cell... let userPost = self.userPosts[indexPath.row] as! [String: AnyObject] cell.profileTitleLabel.text = userPost["title"] as? String cell.profileContentView.text = userPost["content"] as? String cell.profileTimeAndDateLabel.text = userPost["time"] as? String cell.profileUsernameLabel.text = userPost["username"] as? String cell.profileLocationAddress.text = userPost["adress"] as? String if let imageName = userPost["image"] as? String { let imageRef = Storage.storage().reference().child("images/\(imageName)") imageRef.getData(maxSize: 25 * 1024 * 1024) { (data, error) -> Void in if error == nil { //successfull let downloadedImage = UIImage(data: data!) cell.profileImageView.image = downloadedImage }else { // error print("there was an error downloading image: \(String(describing: error?.localizedDescription))") } } } return cell } ,如下所示:

[1]

答案 1 :(得分:0)

这样的XQuery

for $r in /root/detail/record 
  return <record>
         {
           <MasterValue>
           {
             /root/master/record[(ID/text())[1]=($r/MasterID/text())[1]]/Value/text()
           }
           </MasterValue> 
           | $r/*
           }
        </record>

将返回

<record>
   <ID>A</ID>
   <MasterID>1</MasterID>
   <Value>Somevalue a</Value>
   <MasterValue>One</MasterValue>
</record>
<record>
   <ID>B</ID>
   <MasterID>2</MasterID>
   <Value>Somevalue b</Value>
   <MasterValue>Two</MasterValue>
</record>
<record>
   <ID>C</ID>
   <MasterID>1</MasterID>
   <Value>Somevalue c</Value>
   <MasterValue>One</MasterValue>
</record>
<record>
   <ID>D</ID>
   <Value>Somevalue d</Value>
   <MasterValue/>
</record>

答案 2 :(得分:0)

似乎没有办法使用MSXML做到这一点,所以我需要尝试别的东西来使X-Path更加动态,而不需要修改特定XML结构的代码。