我正在尝试从包含大量具有重复名称的元素的 XML 文件中解析信息。
以下是我尝试解析的文件类型的示例,仅包含一条记录:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<!--
Start of the FIRST record.
-->
<dict>
<key>80211D_IE</key>
<dict>
<key>IE_KEY_80211D_CHAN_INFO_ARRAY</key>
<array>
<dict>
<key>IE_KEY_80211D_FIRST_CHANNEL</key>
<integer>1</integer>
<key>IE_KEY_80211D_MAX_POWER</key>
<integer>27</integer>
<key>IE_KEY_80211D_NUM_CHANNELS</key>
<integer>11</integer>
</dict>
</array>
<key>IE_KEY_80211D_COUNTRY_CODE</key>
<string>US</string>
</dict>
<key>AGE</key>
<integer>0</integer>
<key>AP_MODE</key>
<integer>2</integer>
<key>BEACON_INT</key>
<integer>100</integer>
<key>BSSID</key>
<string>ac:5d:10:73:c3:11</string>
<key>CAPABILITIES</key>
<integer>1073</integer>
<key>CHANNEL</key>
<integer>2</integer>
<key>CHANNEL_FLAGS</key>
<integer>10</integer>
<key>IE</key>
<data>
AAZPbGl2ZXIBCIKEiwwSlhgkAwECBwZVUyABCxswGAEAAA+sAgIAAA+sBAAP
rAIBAAAPrAIAAN0aAFDyAQEAAFDyAgIAAFDyBABQ8gIBAABQ8gIqAQAyBDBI
YGw=
</data>
<key>NOISE</key>
<integer>0</integer>
<key>RATES</key>
<array>
<integer>1</integer>
<integer>2</integer>
<integer>5</integer>
<integer>6</integer>
<integer>9</integer>
<integer>11</integer>
<integer>12</integer>
<integer>18</integer>
<integer>24</integer>
<integer>36</integer>
<integer>48</integer>
<integer>54</integer>
</array>
<key>RSN_IE</key>
<dict>
<key>IE_KEY_RSN_AUTHSELS</key>
<array>
<integer>2</integer>
</array>
<key>IE_KEY_RSN_MCIPHER</key>
<integer>2</integer>
<key>IE_KEY_RSN_UCIPHERS</key>
<array>
<integer>4</integer>
<integer>2</integer>
</array>
<key>IE_KEY_RSN_VERSION</key>
<integer>1</integer>
</dict>
<key>RSSI</key>
<integer>-74</integer>
<key>SSID</key>
<data>
T2xpdmVy
</data>
<key>SSID_STR</key>
<string>Oliver</string>
<key>WPA_IE</key>
<dict>
<key>IE_KEY_WPA_AUTHSELS</key>
<array>
<integer>2</integer>
</array>
<key>IE_KEY_WPA_MCIPHER</key>
<integer>2</integer>
<key>IE_KEY_WPA_UCIPHERS</key>
<array>
<integer>4</integer>
<integer>2</integer>
</array>
<key>IE_KEY_WPA_VERSION</key>
<integer>1</integer>
</dict>
</dict>
<!--
End of the FIRST record.
In reality, more records follow.
-->
</array>
</plist>
我遇到的问题是,我想从本质上展平每个观察结果(上例中只有一个观察结果),以便第一个中的每个元素<array>
(即每个<dict>
within <array>
) 是数据框中的一行,其中的每个元素<dict>
是一列,由适当的名称命名<key>
.
我已经尝试过以下功能XML
包,主要是xmlToList
,但还没有完全弄清楚解析 XML 数据的正确方法。
Edit:
我想要的输出或多或少是将每个记录展平为数据框或列表中的一行,以便可以通过键轻松访问值。我不一定关心保留任何层次结构,例如每条记录都会有<key>80211D_IE</key>
随后是一个dict
包含实际信息——<key>80211D_IE</key>
不是必需的,因为它不包含任何真实信息,而只是一组项目的不必要的分组。我可以将其存储为列表,例如mydata$record1$X80211D_IE$I.E._KEY_80211D_CHAN_INFO_ARRAY$IE_KEY_80211D_FIRST_CHANNEL
,或者在像这样的数据框中mydata[1, 'I.E._KEY_80211D_FIRST_CHANNEL']
.
我现在遇到的最大问题是这个 XML 结构似乎不太适合解析。例如,如果我想将 XML 子集化为记录,其中SSID_STR
匹配一个字符串,我不能只使用xmlToList
因为它不知道键应该与其值相关联。所以我得到一个这样的列表:
> str(xmlToList("path/to/my/file.xml"), max.level=2)
List of 2
$ array :List of 25
..$ dict:List of 36
..$ dict:List of 32
..$ dict:List of 32
..$ dict:List of 38
..$ dict:List of 36
..$ dict:List of 34
..$ dict:List of 34
..$ dict:List of 34
..$ dict:List of 34
..$ dict:List of 34
..$ dict:List of 32
..$ dict:List of 38
..$ dict:List of 38
..$ dict:List of 34
..$ dict:List of 36
..$ dict:List of 34
..$ dict:List of 36
..$ dict:List of 34
..$ dict:List of 36
..$ dict:List of 36
..$ dict:List of 40
..$ dict:List of 42
..$ dict:List of 36
..$ dict:List of 38
..$ dict:List of 38
$ .attrs: Named chr "1.0"
..- attr(*, "names")= chr "version"
看看其中的一个
> str(xmlToList("path/to/my/file.xml")$array[[1]], max.level = 1)
List of 36
$ key : chr "80211D_IE"
$ dict :List of 4
$ key : chr "AGE"
$ integer: chr "0"
$ key : chr "AP_MODE"
$ integer: chr "2"
$ key : chr "BEACON_INT"
$ integer: chr "100"
$ key : chr "BSSID"
$ string : chr "a:18:a:31:0:83"
$ key : chr "CAPABILITIES"
$ integer: chr "4145"
$ key : chr "CHANNEL"
$ integer: chr "11"
$ key : chr "CHANNEL_FLAGS"
$ integer: chr "10"
$ key : chr "HT_CAPS_IE"
$ dict :List of 12
$ key : chr "HT_IE"
$ dict :List of 34
$ key : chr "IE"
$ data : chr "\n\t\tAAR0ZXN0AQiWlgwSGCQwSAMBCwcGVVMgAQseKgEDMBgBAAAPrAICAAAPrAQA\n\t\tD6wCAQAAD6wCAAAyAmBsRgVzwAEAADMCDAstGowRG///AAAAAAAAAAA"| __truncated__
$ key : chr "NOISE"
$ integer: chr "0"
$ key : chr "RATES"
$ array :List of 9
$ key : chr "RSN_IE"
$ dict :List of 8
$ key : chr "RSSI"
$ integer: chr "-86"
$ key : chr "SSID"
$ data : chr "\n\t\tdGVzdA==\n\t\t"
$ key : chr "SSID_STR"
$ string : chr "test"
$ key : chr "WPA_IE"
$ dict :List of 8
很容易看出,实际上只有 18 个项目,但密钥作为自己的项目存储(总共 36 个)。
The xmlToList
函数实际上是almost我希望它做什么——而是使用相应键的值来命名包含数据的列表的元素。
这看起来像:
List of 18
$ AGE : chr "0"
$ AP_MODE : chr "2"
$ BEACON_INT : chr "100"
$ BSSID : chr "a:18:a:31:0:83"
$ CAPABILITIES : chr "4145"
$ CHANNEL : chr "11"
$ CHANNEL_FLAGS: chr "10"
$ HT_CAPS_IE :List of 12
$ HT_IE :List of 34
$ IE : chr "\n\t\tAAR0ZXN0AQiWlgwSGCQwSAMBCwcGVVMgAQseKgEDMBgBAAAPrAICAAAPrAQA\n\t\tD6wCAQAAD6wCAAAyAmBsRgVzwAEAADMCDAstGowRG///AAAAAAAAAAA"| __truncated__
$ NOISE : chr "0"
$ RATES :List of 9
$ RSN_IE :List of 8
$ RSSI : chr "-86"
$ SSID : chr "\n\t\tdGVzdA==\n\t\t"
$ SSID_STR : chr "test"
$ WPA_IE :List of 8
$ X80211D_IE :List of 4
在这个假设的输出中,使用适当的键很容易获取值。此外,继续取消嵌套列表(因为不需要分组结构)以生成数据框将很容易。