You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R语言中提取嵌套XML并将含ASCII实体名称的XML转换为标准XML

解决嵌套XML提取与实体解码问题

我来帮你搞定从XMP元数据里提取嵌套XML并转成标准格式的需求,之前你遇到的问题主要是命名空间匹配错误和实体解码不彻底,下面是具体的解决方案:

步骤分析

  1. 正确定位嵌套XML所在的节点(绕过命名空间的坑)
  2. 解码所有XML转义实体(比如<、
这类)
  3. 解析解码后的文本为XML并格式化输出

完整R代码实现

library(xml2)
library(stringi)

# 你的原始XMP XML内容
raw_xmp_xml <- '<?xpacket begin="???" id="W5M0MpCehiHzreSzNTczkc9d"?> 
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.4-c006 80.159825, 2016/09/16-03:31:08 "> 
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
<rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:pdfx="http://ns.adobe.com/pdfx/1.3/" xmlns:pdf="http://ns.adobe.com/pdf/1.3/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:pdfx_1_="ns.adobe.org/pdfx/1.3/"> 
<xmp:CreateDate>2021-05-30T11:17:35+02:00</xmp:CreateDate> 
<xmp:CreatorTool>TeX</xmp:CreatorTool> 
<xmp:ModifyDate>2021-05-30T12:12:25+02:00</xmp:ModifyDate> 
<xmp:MetadataDate>2021-05-30T12:12:25+02:00</xmp:MetadataDate> 
<pdfx:PTEX.Fullbanner>This is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019) kpathsea version 6.3.1</pdfx:PTEX.Fullbanner> 
<pdf:Producer>pdfTeX-1.40.20</pdf:Producer> 
<pdf:Trapped>Unknown</pdf:Trapped> 
<pdf:Keywords/> 
<dc:format>application/pdf</dc:format> 
<xmpMM:DocumentID>uuid:38d0617c-0385-5941-a87d-cc4a1e54bd76</xmpMM:DocumentID> 
<xmpMM:InstanceID>uuid:d056c61c-55c6-5f44-8c0e-fe6e911c2ed9</xmpMM:InstanceID> 
<pdfwe:dafra>&#xA;&#xA;&lt;?xml version="1.0"?&gt;&#xA;&#x9;&lt;dataframe name="expData" &#xA;&#x9;&#x9;xmlns="url"&#xA;&#x9;&#x9;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&#xA;&#x9;&#x9;xsi:schemaLocation="url"&gt;&#xA;&#x9;&#x9;&lt;column name="DATA" type="ratio"&gt;&#xA;&#x9;&#x9;&#x9;&lt;value&gt;14&lt;/value&gt;&#xA;&#x9;&#x9;&#x9;&lt;value&gt;18&lt;/value&gt;&#xA;&#x9;&#x9;&#x9;&lt;value&gt;21&lt;/value&gt;&#xA;&#x9;&#x9;&#x9;&lt;value&gt;35&lt;/value&gt;&#xA;&#x9;&#x9;&#x9;&lt;value&gt;44&lt;/value&gt;&#xA;&#x9;&#x9;&#x9;&lt;value&gt;50&lt;/value&gt;&#xA;&#x9;&#x9;&#x9;&lt;value&gt;3&lt;/value&gt;&#xA;&#x9;&#x9;&#x9;&lt;value&gt;5&lt;/value&gt;&#xA;&#x9;&#x9;&#x9;&lt;value&gt;7&lt;/value&gt;&#xA;&#x9;&#x9;&lt;/column&gt;&#xA;&#x9;&lt;/dataframe&gt;&#xA;&#xA;&#x9;&#x9;&#x9;</pdfwe:dafra> 
</rdf:Description> 
</rdf:RDF> 
</x:xmpmeta> 
<?xpacket end="w"?>'

# 1. 解析原始XMP XML
doc <- read_xml(raw_xmp_xml)

# 2. 提取嵌套的转义XML文本(用local-name绕过命名空间未声明的问题)
escaped_content <- xml_text(xml_find_all(doc, ".//*[local-name()='dafra']"))

# 3. 解码所有XML实体(包括标签、换行、制表符)
unescaped_content <- stri_unescape_xml(escaped_content)

# 4. 解析为标准XML并格式化输出
dataframe_xml <- read_xml(unescaped_content)
formatted_result <- xml_serialize(dataframe_xml, NULL, options = "format")

# 打印结果
cat(as.character(formatted_result))

为什么之前的方法没生效?

  • 命名空间问题:你用pdfwe:dafra查询,但原始XML的<rdf:Description>节点并没有声明xmlns:pdfwe命名空间,导致xml2无法匹配到节点。用local-name()='dafra'可以忽略命名空间,直接匹配节点名称。
  • 实体解码不彻底:xml_text()提取的是转义后的原始文本,需要用专门的XML实体解码函数(比如stri_unescape_xml)来还原所有转义字符,手动拼接<x>标签的方法无法处理所有类型的实体。

运行结果

执行代码后会输出你想要的标准XML:

<?xml version="1.0" encoding="UTF-8"?>
<dataframe name="expData" xmlns="url" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="url">
  <column name="DATA" type="ratio">
    <value>14</value>
    <value>18</value>
    <value>21</value>
    <value>35</value>
    <value>44</value>
    <value>50</value>
    <value>3</value>
    <value>5</value>
    <value>7</value>
  </column>
</dataframe>

内容的提问来源于stack exchange,提问作者Felipe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 17:37:39