VBA MSXML:如何避免XPath查询结果中插入命名空间URI
问题:MSXML2提取XML节点时避免自动插入命名空间声明
原始KML文件结构
<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom"> <Document> <name>data.kml</name> <Folder> <name>Temporary Places</name> <open>1</open> <Placemark> <name>Untitled Placemark</name> <LookAt> <gx:TimeStamp><when>2000</when> </gx:TimeStamp> <longitude>-107.105195493537</longitude> <latitude>40.11614841516315</latitude> <altitude>0</altitude> <heading>0.0484794930795848</heading> <tilt>0</tilt> <range>209596.4338269165</range> <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode> </LookAt> <styleUrl>#m_ylw-pushpin</styleUrl> <Point> <gx:drawOrder>1</gx:drawOrder> <coordinates>-107.105195493537,40.11614841516316,0</coordinates> </Point> </Placemark> </Folder> </Document> </kml>
执行的VBA代码
Set xNode = .selectSingleNode("//ns:kml/ns:Document") StrXML = xNode.xml
当前返回的XML结果
<Document> <name>data.kml</name> <Folder> <name>Temporary Places</name> <open>1</open> <Placemark> <name>Untitled Placemark</name> <LookAt> <gx:TimeStamp xmlns:gx="http://www.google.com/kml/ext/2.2"><when>2000</when> </gx:TimeStamp> <longitude>-107.105195493537</longitude> <latitude>40.11614841516315</latitude> <altitude>0</altitude> <heading>0.0484794930795848</heading> <tilt>0</tilt> <range>209596.4338269165</range> <gx:altitudeMode xmlns:gx="http://www.google.com/kml/ext/2.2">relativeToSeaFloor</gx:altitudeMode> </LookAt> <styleUrl>#m_ylw-pushpin</styleUrl> <Point> <gx:drawOrder xmlns:gx="http://www.google.com/kml/ext/2.2">1</gx:drawOrder> <coordinates>-107.105195493537,40.11614841516316,0</coordinates> </Point> </Placemark> </Folder> </Document>
问题
返回的XML中自动添加了原始文件没有的gx命名空间声明,希望获取不包含这些额外声明的XML,能否通过MSXML2实现?
解决方案
方法1:通过导入节点到带命名空间的新文档避免重复声明
MSXML2输出节点XML时,会确保命名空间可解析。由于Document节点本身没有gx命名空间声明(原始声明在父节点kml上),所以会自动在子节点补全。可以将节点导入到已包含该命名空间的新文档中,避免重复添加:
Dim originalDoc As MSXML2.DOMDocument60 Dim newDoc As MSXML2.DOMDocument60 Dim xNode As MSXML2.IXMLDOMNode Dim importedNode As MSXML2.IXMLDOMNode Dim rootNode As MSXML2.IXMLDOMElement Set originalDoc = New MSXML2.DOMDocument60 originalDoc.preserveWhiteSpace = True originalDoc.Load "你的KML文件路径" ' 或加载XML字符串:originalDoc.LoadXML "XML内容" ' 设置命名空间映射,用于XPath查询 originalDoc.SetProperty "SelectionNamespaces", "xmlns:ns='http://www.opengis.net/kml/2.2'" ' 获取目标Document节点 Set xNode = originalDoc.SelectSingleNode("//ns:kml/ns:Document") Set newDoc = New MSXML2.DOMDocument60 newDoc.preserveWhiteSpace = True ' 添加XML声明和带gx命名空间的根节点 newDoc.AppendChild newDoc.CreateProcessingInstruction("xml", "version='1.0' encoding='UTF-8'") Set rootNode = newDoc.CreateElement("tempRoot") rootNode.SetAttribute "xmlns:gx", "http://www.google.com/kml/ext/2.2" newDoc.AppendChild rootNode ' 导入节点到新文档,保留所有子节点 Set importedNode = newDoc.ImportNode(xNode, True) rootNode.AppendChild importedNode ' 此时提取的节点XML不会包含额外的gx命名空间声明 StrXML = importedNode.xml
方法2:字符串替换移除额外声明(简单场景适用)
如果不需要严格的DOM操作,直接对返回的XML字符串做替换,移除子节点上的gx命名空间声明:
StrXML = xNode.xml StrXML = Replace(StrXML, " xmlns:gx=""http://www.google.com/kml/ext/2.2""", "")
内容的提问来源于stack exchange,提问作者vbaToad
相关产品推荐
相关产品推荐

