xml2软件包(R)中的xml_find_all函数找不到相关节点

时间:2019-04-17 12:07:56

标签: r xml xml2

我在R中使用xml2包访问xml数据,发现它在不同的xml_documents上表现不同。

在这个宠物的例子中

library(xml2)
doc <- read_xml( "<MEMBERS>
                      <CUSTOMER>
                         <ID>178</ID>
                         <FIRST.NAME>Alvaro</FIRST.NAME>
                         <LAST.NAME>Juarez</LAST.NAME>
                         <ADDRESS>123 Park Ave</ADDRESS>
                         <ZIP>57701</ZIP>
                      </CUSTOMER>
                      <CUSTOMER>
                         <ID>934</ID>
                         <FIRST.NAME>Janette</FIRST.NAME>
                         <LAST.NAME>Johnson</LAST.NAME>
                         <ADDRESS>456 Candy Ln</ADDRESS>
                         <ZIP>57701</ZIP>
                      </CUSTOMER>  
                   </MEMBERS>")
doc
{xml_document}
<MEMBERS>
[1] <CUSTOMER>\n  <ID>178</ID>\n  <FIRST.NAME>Alvaro</FIRST.NAME>\n  <LAST.NAME>Juarez</LAST.NAME>\n  <ADDRESS>12 ...
[2] <CUSTOMER>\n  <ID>934</ID>\n  <FIRST.NAME>Janette</FIRST.NAME>\n  <LAST.NAME>Johnson</LAST.NAME>\n  <ADDRESS> ...

我可以运行以下代码

xml_find_all(doc, "//FIRST.NAME")
{xml_nodeset (2)}
[1] <FIRST.NAME>Alvaro</FIRST.NAME>
[2] <FIRST.NAME>Janette</FIRST.NAME>

为我提供了预期的输出(找到所有带有“ FIRST.NAME”标签的节点)。

但是,如果我对this xml文件执行相同的操作:

example <- read_xml(file.path("~/Downloads", "uniprot_subset.xml"))
> example
{xml_document}
<uniprot>
 [1] <entry xmlns="http://uniprot.org/uniprot" dataset="Swiss-Prot" created="2011-06-28" modified="2019-01-16" version="35">\n  <accession>Q6GZX4</accession>\n  <name>001R_FRG3G</name>\n  <protein>\n    <recommendedName>\n      <fullName>Putative tr ...
 [2] <entry xmlns="http://uniprot.org/uniprot" dataset="Swiss-Prot" created="2011-06-28" modified="2019-01-16" version="36">\n  <accession>Q6GZX3</accession>\n  <name>002L_FRG3G</name>\n  <protein>\n    <recommendedName>\n      <fullName>Uncharacter ...
 [3] <entry xmlns="http://uniprot.org/uniprot" dataset="Swiss-Prot" created="2009-06-16" modified="2018-06-20" version="22">\n  <accession>Q197F8</accession>\n  <name>002R_IIV3</name>\n  <protein>\n    <recommendedName>\n      <fullName>Uncharacteri ...
 [4] <entry xmlns="http://uniprot.org/uniprot" dataset="Swiss-Prot" created="2009-06-16" modified="2017-09-27" version="18">\n  <accession>Q197F7</accession>\n  <name>003L_IIV3</name>\n  <protein>\n    <recommendedName>\n      <fullName>Uncharacteri ...
 [5] <entry xmlns="http://uniprot.org/uniprot" dataset="Swiss-Prot" created="2011-06-28" modified="2019-01-16" version="31">\n  <accession>Q6GZX2</accession>\n  <name>003R_FRG3G</name>\n  <protein>\n    <recommendedName>\n      <fullName>Uncharacter ...
 [6] <entry xmlns="http://uniprot.org/uniprot" dataset="Swiss-Prot" created="2011-06-28" modified="2017-09-27" version="29">\n  <accession>Q6GZX1</accession>\n  <name>004R_FRG3G</name>\n  <protein>\n    <recommendedName>\n      <fullName>Uncharacter ...
 [7] <entry xmlns="http://uniprot.org/uniprot" dataset="Swiss-Prot" created="2009-06-16" modified="2017-09-27" version="24">\n  <accession>Q197F5</accession>\n  <name>005L_IIV3</name>\n  <protein>\n    <recommendedName>\n      <fullName>Uncharacteri ...
 [8] <entry xmlns="http://uniprot.org/uniprot" dataset="Swiss-Prot" created="2011-06-28" modified="2019-01-16" version="38">\n  <accession>Q6GZX0</accession>\n  <name>005R_FRG3G</name>\n  <protein>\n    <recommendedName>\n      <fullName>Uncharacter ...
 [9] <entry xmlns="http://uniprot.org/uniprot" dataset="Swiss-Prot" created="2009-06-16" modified="2019-01-16" version="44">\n  <accession>Q91G88</accession>\n  <name>006L_IIV6</name>\n  <protein>\n    <recommendedName>\n      <fullName>Putative Kil ...
[10] <entry xmlns="http://uniprot.org/uniprot" dataset="Swiss-Prot" created="2011-06-28" modified="2017-09-27" version="27">\n  <accession>Q6GZW9</accession>\n  <name>006R_FRG3G</name>\n  <protein>\n    <recommendedName>\n      <fullName>Uncharacter ...

它的行为有所不同

xml_find_all(example, "//accession")
{xml_nodeset (0)}

基本上,它将找不到带有“ accession”标签的任何节点,即使它们存在并且可以通过其他功能(例如,使用

xml_children(xml_children(example)[1])[1]
{xml_nodeset (1)}
[1] <accession>Q6GZX4</accession>

谁能告诉我为什么xml_find_all函数在后一个示例中找不到任何节点?

1 个答案:

答案 0 :(得分:1)

发生这种情况是因为您的宠物示例不包含名称空间,但是第二个XML文件包含名称空间。

example %>% xml_ns()

d1  <-> http://uniprot.org/uniprot
d2  <-> http://uniprot.org/uniprot
d3  <-> http://uniprot.org/uniprot
d4  <-> http://uniprot.org/uniprot
d5  <-> http://uniprot.org/uniprot
d6  <-> http://uniprot.org/uniprot
d7  <-> http://uniprot.org/uniprot
d8  <-> http://uniprot.org/uniprot
d9  <-> http://uniprot.org/uniprot
d10 <-> http://uniprot.org/uniprot

由于每个条目具有相同的名称空间,在这种情况下,最简单的方法可能是剥离(删除)名称空间:

example %>% xml_ns_strip()

并且xml_find_all现在应该可以正常工作了:

example %>% xml_find_all("//accession")

{xml_nodeset (10)}
 [1] <accession>Q6GZX4</accession>
 [2] <accession>Q6GZX3</accession>
 [3] <accession>Q197F8</accession>
 [4] <accession>Q197F7</accession>
 [5] <accession>Q6GZX2</accession>
 [6] <accession>Q6GZX1</accession>
 [7] <accession>Q197F5</accession>
 [8] <accession>Q6GZX0</accession>
 [9] <accession>Q91G88</accession>
[10] <accession>Q6GZW9</accession>

如果您想保留名称空间,则可以访问以下内容:

example %>% xml_find_all("//d1:accession")

之所以在这种情况下起作用,是因为为第一个条目的名称空间指定的默认名称d1映射到所有条目的相同名称空间。