在R语言中提取嵌套XML并将含ASCII实体名称的XML转换为标准XML
解决嵌套XML提取与实体解码问题
我来帮你搞定从XMP元数据里提取嵌套XML并转成标准格式的需求,之前你遇到的问题主要是命名空间匹配错误和实体解码不彻底,下面是具体的解决方案:
步骤分析
- 正确定位嵌套XML所在的节点(绕过命名空间的坑)
- 解码所有XML转义实体(比如
<、
这类) - 解析解码后的文本为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>

<?xml version="1.0"?>
	<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>

			</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
相关产品推荐
相关产品推荐

