使用 VBS 访问 KML 文件中的特定命名节点
Access specific named node in KML file using VBS
我正在从 KML 文件中提取邮政编码和坐标(以构建一个巨大的 Javascript 数组)但是我无法定位名为 'POA_2006' 的节点中的值我是 运行 这在 .vbs 文件中。我可以使用 .singleNode 或 .namedItem 通常使用 XML 文件来执行此操作,但无法让其中任何一个与看起来像这样的 KML 文件一起使用(我无法控制 KML 文件。它有一个巨大的 180mb包含澳大利亚所有邮政编码的所有坐标形状的文件):
<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="root_doc">
<Schema name="postcode" id="postcode">
<SimpleField name="STATE_2006" type="string"></SimpleField>
<SimpleField name="POA_2006" type="string"></SimpleField>
</Schema>
<Folder><name>postcode</name>
<Placemark>
<Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>
<ExtendedData><SchemaData schemaUrl="#postcode">
<SimpleData name="STATE_2006">1</SimpleData>
<SimpleData name="POA_2006">2000</SimpleData>
</SchemaData></ExtendedData>
<MultiGeometry><Polygon><altitudeMode>relativeToGround</altitudeMode><outerBoundaryIs><LinearRing><altitudeMode>relativeToGround</altitudeMode><coordinates>151.20118275199999,-33.873293252 ,-33.851193004 151.19797801600001</coordinates></LinearRing></outerBoundaryIs></Polygon></MultiGeometry>
</Placemark>
</Folder>
</Document></kml>
这是我被迫使用的代码,但我不喜欢我必须这样做的事实 'if (i mod 1.5) = 1 then' 总是忽略第一个节点以确保它跳到第二个节点其中包含我的邮政编码
function readKLMFileAndWriteToFile(toFileName, fromFileName)
Dim objxml, fso, filetxt, getname, path
Set objxml = CreateObject("MSXML2.DOMDocument")
objxml.async = False
objxml.load (fromFileName)
Set fso = CreateObject("Scripting.FileSystemObject")
Set filetxt = fso.CreateTextFile(toFileName, True)
path = fso.GetAbsolutePathName(toFileName)
getname = fso.GetFileName(path)
writeLog "A file called " & getname & " was created"
Dim SimpleData, SimpleDataLen, coords,coordsLen,i, ctr, i2
set SimpleData = objxml.getElementsByTagName("SimpleData")
SimpleDataLen = SimpleData.length-1
set coords = objxml.getElementsByTagName("coordinates")
coordsLen = coords.length-1
ctr = 0
for i = 0 to SimpleDataLen
'filetxt.write i & " mod = " & i mod 1.5 & "]" & vbcrlf
'why can I not target the named 'POA_2006' node! Use this workaround to only show every second SimpleData node
if (i mod 1.5) = 1 then
filetxt.write "var postcode_" & SimpleData.item(i).Text & " = ["
filetxt.write replace(coords.item(ctr).Text, " ", ",") & "];" & vbcrlf
ctr = ctr+1
end if
next
filetxt.Close
end function
关于如何直接定位节点的任何想法?
您可以通过 XPath 选择查询来定位它。一开始选择选择语言
' put this in before .load()
objxml.SetProperty "SelectionLanguage", "XPath"
那么您可能还需要将命名空间添加到 XML 文档的 SelectionNamespaces
属性 中:
objxml.SetProperty "SelectionNamespaces", "xmlns:k=""http://www.opengis.net/kml/2.2"""
你需要给它起个名字——这里我用的是k
。现在可以直接查询有问题的节点:
set SimpleData = objxml.SelectSingleNode("//k:SimpleData[@name='POA_2006']")
SelectSingleNode()
方法 returns 单个对象而不是集合,因此您只需使用 SimpleData.text
即可访问节点的上下文。
filetxt.write "var postcode_" & SimpleData.Text & " = ["
我正在从 KML 文件中提取邮政编码和坐标(以构建一个巨大的 Javascript 数组)但是我无法定位名为 'POA_2006' 的节点中的值我是 运行 这在 .vbs 文件中。我可以使用 .singleNode 或 .namedItem 通常使用 XML 文件来执行此操作,但无法让其中任何一个与看起来像这样的 KML 文件一起使用(我无法控制 KML 文件。它有一个巨大的 180mb包含澳大利亚所有邮政编码的所有坐标形状的文件):
<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="root_doc">
<Schema name="postcode" id="postcode">
<SimpleField name="STATE_2006" type="string"></SimpleField>
<SimpleField name="POA_2006" type="string"></SimpleField>
</Schema>
<Folder><name>postcode</name>
<Placemark>
<Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>
<ExtendedData><SchemaData schemaUrl="#postcode">
<SimpleData name="STATE_2006">1</SimpleData>
<SimpleData name="POA_2006">2000</SimpleData>
</SchemaData></ExtendedData>
<MultiGeometry><Polygon><altitudeMode>relativeToGround</altitudeMode><outerBoundaryIs><LinearRing><altitudeMode>relativeToGround</altitudeMode><coordinates>151.20118275199999,-33.873293252 ,-33.851193004 151.19797801600001</coordinates></LinearRing></outerBoundaryIs></Polygon></MultiGeometry>
</Placemark>
</Folder>
</Document></kml>
这是我被迫使用的代码,但我不喜欢我必须这样做的事实 'if (i mod 1.5) = 1 then' 总是忽略第一个节点以确保它跳到第二个节点其中包含我的邮政编码
function readKLMFileAndWriteToFile(toFileName, fromFileName)
Dim objxml, fso, filetxt, getname, path
Set objxml = CreateObject("MSXML2.DOMDocument")
objxml.async = False
objxml.load (fromFileName)
Set fso = CreateObject("Scripting.FileSystemObject")
Set filetxt = fso.CreateTextFile(toFileName, True)
path = fso.GetAbsolutePathName(toFileName)
getname = fso.GetFileName(path)
writeLog "A file called " & getname & " was created"
Dim SimpleData, SimpleDataLen, coords,coordsLen,i, ctr, i2
set SimpleData = objxml.getElementsByTagName("SimpleData")
SimpleDataLen = SimpleData.length-1
set coords = objxml.getElementsByTagName("coordinates")
coordsLen = coords.length-1
ctr = 0
for i = 0 to SimpleDataLen
'filetxt.write i & " mod = " & i mod 1.5 & "]" & vbcrlf
'why can I not target the named 'POA_2006' node! Use this workaround to only show every second SimpleData node
if (i mod 1.5) = 1 then
filetxt.write "var postcode_" & SimpleData.item(i).Text & " = ["
filetxt.write replace(coords.item(ctr).Text, " ", ",") & "];" & vbcrlf
ctr = ctr+1
end if
next
filetxt.Close
end function
关于如何直接定位节点的任何想法?
您可以通过 XPath 选择查询来定位它。一开始选择选择语言
' put this in before .load()
objxml.SetProperty "SelectionLanguage", "XPath"
那么您可能还需要将命名空间添加到 XML 文档的 SelectionNamespaces
属性 中:
objxml.SetProperty "SelectionNamespaces", "xmlns:k=""http://www.opengis.net/kml/2.2"""
你需要给它起个名字——这里我用的是k
。现在可以直接查询有问题的节点:
set SimpleData = objxml.SelectSingleNode("//k:SimpleData[@name='POA_2006']")
SelectSingleNode()
方法 returns 单个对象而不是集合,因此您只需使用 SimpleData.text
即可访问节点的上下文。
filetxt.write "var postcode_" & SimpleData.Text & " = ["