xpath 只选择相关节点
Posted
技术标签:
【中文标题】xpath 只选择相关节点【英文标题】:xpath just select the relevant nodes 【发布时间】:2020-05-10 19:18:12 【问题描述】:嗨,我有一些 xml 文件,我正在尝试通过从 xml 中获取“mapfile”属性值(如下所示)来使用 xpath,然后从外部 mapfile 中获取所有“key”值,我没问题。
然后我需要从下面的 xml 文件中获取与此映射文件相对应的所有“关键”数字。问题是我可以将它们全部取出,但我需要取出它们并单独检查每个文件,而不是全部。
xml 被分成“listsections”,每个“listsection”都有一个映射文件。我想对照地图文件中的“键”值检查“列表部分”中的“键”值。
所以我尝试的是
//get the list of mapfiles
XmlNodeList mapfiles = xmlDoc.SelectNodes("//a:listsection/a:views/a:explodeddiagram", nsmgr);
//get the mapfiles
foreach (XmlNode mapfile in mapfiles)
string mapfilename = mapfile.Attributes["mapfile"].Value;
//load the mapfile and read it and get the key values from it.
XmlDocument xmlDockey = new XmlDocument();
xmlDochot.Load(parentdir + "\\" + mapfilename);
XmlNodeList xmlkeyfrommapfile = xmlDockey.SelectNodes("//*[name()='area'][@key]");
foreach (XmlNode keynode in xmlkeyfrommapfile)
string keyTextmapfile = keynode.Attributes["key"].Value;
//So here i've got all the values I need for each "mapfile"
list1.Add(keyTextmapfile );
//now I get the values of the "key" from the xml file (xml shown below)
//get the values for the keys from the list file (xml shown below)
XmlNodeList keysfromlistfile = xmlDoc.SelectNodes("//*[name()='key']");
foreach (XmlNode keyfromlistfile in keysfromlistfile)
string keyTextlistfile = keyfromlistfile.InnerText;
list2.Add(keyTextlistfile);
重申一下:我明白了。我只想检查每个文件中同一“listsection”中的“key”值有多个“listsections”有时超过 20 个。
<Thislist>
<listsection>
<views>
<explodeddiagram title="Some image title1" graphicfile="SomeFilename1.tif" mapfile="SomeFilename1.xml" />
</views>
<rows>
<row>
<key>1</key>
<remark>(Generic Remark 1)</remark>
<part>
<number>25376.0000</number>
<description>Generic Description</description>
</part>
<qty>1</qty>
</row>
<row>
<key>2</key>
<remark>(Generic Remark 4)</remark>
<part>
<number>253767890002</number>
<description>Generic Description</description>
</part>
<qty>1</qty>
</row>
<row>
<key>2</key>
<remark>(Generic Remark 3)</remark>
<part>
<number>253764560001</number>
<description>Generic Description</description>
</part>
<qty>1</qty>
</row>
<row>
<key>3</key>
<remark>(Generic Remark 5)</remark>
<part>
<number>209213231004</number>
<description>Generic Description</description>
</part>
<qty>1</qty>
</row>
</rows>
</listsection>
<listsection>
<views>
<explodeddiagram title="Some image title2" graphicfile="SomeFilename2.tif" mapfile="SomeFilename2.xml" />
</views>
<rows>
<row>
<key>1</key>
<remark>(Generic Remark 6)</remark>
<part>
<number>25376656560000</number>
<description>Cover Assy, Top SST</description>
</part>
<qty>1</qty>
</row>
<row>
<key>2</key>
<remark>(Generic Remark 7)</remark>
<part>
<number>2537677902</number>
<description>Generic Description</description>
</part>
<qty>1</qty>
</row>
<row>
<key>2</key>
<remark>(Generic Remark 8)</remark>
<part>
<number>25376457881</number>
<description>Generic Description</description>
</part>
<qty>1</qty>
</row>
<row>
<key>3</key>
<remark>(Generic Remark 9)</remark>
<part>
<number>209288004</number>
<description>Generic Description</description>
</part>
<qty>1</qty>
</row>
</rows>
</listsection>
</Thislist>
地图文件示例
<?xml version="1.0" encoding="utf-8"?>
<mapfile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="hotspot.xsd">
<map name="SomeMapName">
<area shape="rect" coords="169,210,199,252" key="3" />
<area shape="rect" coords="2094,881,2124,924" key="1" />
<area shape="rect" coords="2094,1031,2124,1074" key="2" />
<area shape="rect" coords="2094,1145,2124,1187" key="6" />
</map>
</mapfile>
【问题讨论】:
您能否提供您期望的示例输出?它不太清楚你想要完成什么。你有这个 xml.. 然后你有地图文件。你在这个和映射文件中有键。你想用这个 xml 和 mapfiles 中的键做什么 是的。我想要一个来自外部映射文件的所有值的列表,它可以是 1、2、3、6,然后是上述 xml 的输出,用于该部分的所有键mapfile 存在于 1,2,2,3 中。 :在这种情况下,我将能够比较列表并看到该部分的映射文件中有 6,但上面 xml 的“键”中没有。 您能否提供一个外部地图文件的样本 见上,我已经加进去了。 给你两个xml,list2
最后是什么样子的?
【参考方案1】:
我想通了,我需要
-
选择 Thislist xml 文件中的每个部分节点
获取 Thislist xml 文件中每个部分的映射文件值。
将该部分的映射文件中的所有键值读取到一个列表中
从 Thislist xml 文件中获取该部分的所有键值到一个列表中
比较这两个列表,看看是否缺少任何列表
如果有遗漏的请标记
// namespace
var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("a", "http://tempuri.org/XMLSchema.xsd");
//get every section in "Thislist" xml file.
XmlNodeList sections = xmlDoc.SelectNodes("//a:section", nsmgr);
foreach (XmlNode section in sections)
//Get all the explodeddiagrams out for the section
XmlNodeList Views = section.SelectNodes("a:views/a:explodeddiagram", nsmgr);
foreach (XmlNode ExplodedDiagram in Views)
//get the mapfile attribute which gives us the explodeddiagram filename
string mapfile = ExplodedDiagram.Attributes["mapfile"].Value;
//load the mapfile as xmlDocmap
XmlDocument xmlDocmap = new XmlDocument();
xmlDocmap.Load(mapfile);
//go through everymap file in the section and get the key values.
XmlNodeList xmlmapkeylist = xmlDocmap.SelectNodes("//*[name()='area'][@key]");
foreach (XmlNode areakey in xmlmapkeylist)
string keyText = areakey.Attributes["key"].Value;
//add the key values from the mapfile into a list
listmapkeys.Add(keyText);
//get all the key values from the "Thislist" xml file.
XmlNodeList keys = section.SelectNodes("a:partslistsectionrows/a:partslistsectionrow/a:key", nsmgr);
foreach (XmlNode ListKey in keys)
//add the key values from the each section in "Thislist"xml into a list
listsectionkeys.Add(ListKey.InnerText);
foreach (string mapkey in listmapkeys)
//if the section doesn't contain a key value present in the mapfile.
if(!listsectionkeys.Contains(mapkey))
//output the differences or discrepencies this is going to listBox1 in this case
listBox1.Items.Add(hotspot + " not in partslist");
【讨论】:
以上是关于xpath 只选择相关节点的主要内容,如果未能解决你的问题,请参考以下文章