通读XML循环

时间:2014-03-15 21:28:56

标签: vb.net

这是我通过[URL] [1]访问的XML文件的片段,我需要关注它。

<imgdir name="portal">

<imgdir name="0">
<string name="pn" value="sp"/>
<int name="pt" value="0"/>
<int name="x" value="-288"/>
<int name="y" value="27"/>
<int name="tm" value="999999999"/>
<string name="tn" value=""/>
</imgdir>

<imgdir name="1">
<string name="pn" value="in00"/>
<int name="pt" value="7"/>
<int name="x" value="74"/>
<int name="y" value="154"/>
<int name="tm" value="999999999"/>
<string name="tn" value=""/>
<int name="horizontalImpact" value="0"/>
<string name="script" value="talkToMai"/>
<int name="hideTooltip" value="0"/>
<int name="onlyOnce" value="0"/>
<int name="delay" value="0"/>
</imgdir>

<imgdir name="2">
<string name="pn" value="sp"/>
<int name="pt" value="0"/>
<int name="x" value="-349"/>
<int name="y" value="-45"/>
<int name="tm" value="999999999"/>
<string name="tn" value=""/>
</imgdir>

<imgdir name="3">
<string name="pn" value="sp"/>
<int name="pt" value="0"/>
<int name="x" value="257"/>
<int name="y" value="132"/>
<int name="tm" value="999999999"/>
<string name="tn" value=""/>
</imgdir>

<imgdir name="4"> // PLOT THIS PORTAL
<string name="pn" value="east00"/>
<int name="pt" value="2"/>
<int name="x" value="683"/>
<int name="y" value="211"/>
<int name="tm" value="4000026"/>
<string name="tn" value="west00"/>
<int name="horizontalImpact" value="0"/>
<string name="script" value=""/>
<int name="hideTooltip" value="0"/>
<int name="onlyOnce" value="0"/>
<int name="delay" value="0"/>
</imgdir>

<imgdir name="5">
<string name="pn" value="sp"/>
<int name="pt" value="0"/>
<int name="x" value="213"/>
<int name="y" value="101"/>
<int name="tm" value="999999999"/>
<string name="tn" value=""/>
</imgdir>

<imgdir name="6"> // PLOT THIS PORTAL
<string name="pn" value="west00"/>
<int name="pt" value="2"/>
<int name="x" value="-426"/>
<int name="y" value="212"/>
<int name="tm" value="4000020"/>
<string name="tn" value="east00"/>
<string name="script" value=""/>
<int name="hideTooltip" value="0"/>
<int name="delay" value="0"/>
<int name="onlyOnce" value="0"/>
</imgdir>

</imgdir>
</imgdir>

我已经以这种方式阅读了相同的XML但不同的部分。

public static int getWidth(string id)
    {
        try
        {
            var uri = "http://[redacted]/INFO/" + id + ".img.xml";
            var doc = XDocument.Load(uri);

            return (int)doc.Descendants("int").First(x => (string)x.Attribute("name") == "width").Attribute("value");
        }
        catch
        {
            return 0;
        }
    }

如果您查看我上面发布的XML文件的片段,您会注意到我对我需要在我的地图上绘制的“门户”进行了评论(门户网站#4&amp; 6)。 我不明白的是我如何编辑上面的函数来遍历“门户”并检查门户名称'pn'和'tn'是否包含一个值(与值是什么无关)并检查是否附加名称'tm'不包含值999999999,如果上述内容全部为'true',则获取x和y值并使用它们绘制门户网站,并为其余门户网站循环播放。

我已经有了绘制功能,什么不是,我只是不明白如何遍历发布的XML代码,检查某些名称和值(pn&amp; tn&amp; tm),然后抓住x和y如果它满足条件,然后最终在绘图功能中使用它并重复直到没有任何东西。

我希望你理解这一点,谢谢。

1 个答案:

答案 0 :(得分:1)

由于你选择了linq到xml,这将非常容易。基本上,你可以使用Elements()来消除事物,直到得到你想要的东西,或者拿出一些炸药并使用Descendants()。混乱的数量完全取决于你。我将使用Elements()方法。但是Descendants()调用在语法上几乎完全相同,但在这种情况下过滤的数量大致相同。

以下是如何获得imgdir的第一级:

IEnumerable<XElement> data = doc.Elements("imgdir").Where(el => el.HasAttributes);

这将产生所有具有属性{info,back,life等,但没有子元素}的顶级元素。现在我们有一些东西要迭代,你可以遍历元素,或者你可以让你所有的方法都接受一个XElement参数。这样你只能传递你需要的东西。

对于所有可以传递所需数据的方法,只需编写另一个查询来限制更多内容。在提供的案例中,您可以使用:

XElement portal = data.Elements().SingleOrDefault(el => el.Attribute("name").Value == "portal");

现在你有一个XElement可以进一步拆分。是时候获得最精细的imgdir

IEnumerable<XElement> img = portal.Elements("imgdir");

时间迭代并整理出来的小东西:

foreach (var elements in img) // or you can put this in place of "img" : portal.Elements("imgdir")
{
    foreach (var el in elements.Elements())
    {
        if (el.Attribute("name").Value == "pn" && el.Attribute("value").Value != "sp")
        {
            // It's a big 'un!
        }
        else
        {
            // Smaller one.
        }
    }
}

注意:您可以添加tn&amp; tm将其各自的值放入该条件语句中。另外,不要忽略嵌套迭代,你可能会把它放到另一个查询中,但我还没有想到那个。

作为提示,如果你想检查是否有一些数据没有抛出异常,只需输入类似的内容:

if (element != default(XElement))

最后一点,你可以将大部分内容写出来作为一个巨大的查询,但这将是一个调试的噩梦。

编辑:此处有一个重写为getWidth的示例:

public static int GetInt(XElement data, string attribName)
{
    foreach (var element in data.Elements("int"))
    {
        if (element.Attribute("name").Value == attribName)
        {
            return int.Parse(element.Attribute("value").Value);
        }
    }

    throw new ArgumentException("Attribute name does not exist in provided data.");
}

将异常放在那里是个好习惯,因为这个方法可以在程序的上下文中重用,如果另一个开发人员误用它,它会指出问题。

相关问题