在R

时间:2016-04-02 02:45:02

标签: xml r xpath nodes

我今天开始使用R编程,我希望根据xml文件(使用“XML”库)获取一些值。

下面的XML是真实版本的简化版本。

<PDBx:datablock xmlns:PDBx="http://pdbml.pdb.org/schema/pdbx-v40.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" datablockName="1AEW" xsi:schemaLocation="http://pdbml.pdb.org/schema/pdbx-v40.xsd pdbx-v40.xsd">
    <PDBx:atom_siteCategory>
      <PDBx:atom_site id="1">
        <PDBx:Cartn_x>22.250</PDBx:Cartn_x>
        <PDBx:Cartn_y>-18.232</PDBx:Cartn_y>
        <PDBx:Cartn_z>52.362</PDBx:Cartn_z>
        <PDBx:label_atom_id>N</PDBx:label_atom_id>
      </PDBx:atom_site>

      <PDBx:atom_site id="2">
         <PDBx:Cartn_x>22.188</PDBx:Cartn_x>
         <PDBx:Cartn_y>-19.614</PDBx:Cartn_y>
         <PDBx:Cartn_z>52.835</PDBx:Cartn_z>
         <PDBx:label_atom_id>CA</PDBx:label_atom_id>
      </PDBx:atom_site>
.
.
.

我需要提取的是在“label_atom_id”节点中具有值“CA”的所有“atom_site”节点的(x,y,z)坐标。

我已经搜索过了,这就是我找到的:

nodes = getNodeSet(xmltop[[1]], "//atom_siteCategory/atom_site[@label_atom_id='CA']");

我使用xmltop[[1]]因为我想从“atom_siteCategory”节点进行搜索。这是包含所有“atom_site”节点的节点。

此XPATH的问题是atom_site[@label_atom_id='CA]适用于节点属性,而不适用于节点值。

用几句话说: 1)如何将atom_site"CA"节点作为label_atom_id的值。 (使用XPATH)

2)如何从这些节点中提取3个坐标(x,y,z)。 (如何使用此坐标填充data.frame)

1 个答案:

答案 0 :(得分:0)

好的,我找到了解决方案:

#Changes program path to paramenter absolute path
setwd("C:/Users/MyUser/Desktop/App")
#Let's user choose xml file (can be replaced with absolute path)
file = file.choose(new = FALSE)
#Pases xml file
xmlfile = xmlParse(file)
class(xmlfile)
#Gets top node
xmltop = xmlRoot(xmlfile)
#Filters node with XPATH
nodes = getNodeSet(xmltop, "/PDBx:datablock/PDBx:atom_siteCategory/PDBx:atom_site[PDBx:label_atom_id='CA']")
#Turns node list into dataframe
extract = xmlSApply(nodes, function(x) xmlSApply(x, xmlValue))
df = data.frame(t(extract), row.names = NULL)
#Gets column subset (X, Y, Z) coordinates
df2 = df[, c(2,3,4)]
#Changes original names to X, Y and Z
df2 = setNames(df2, c("Cartn_x" = "X", "Cartn_y" = "Y", "Cartn_z" = "Z"))
#Prints the data frame
print.data.frame(df2)

我希望这有助于某人。