Vb.net 通读XML循环

Vb.net 通读XML循环,vb.net,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="

这是我通过[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文件片段,您会注意到我在需要绘制到地图上的“门户”(门户4和6)上添加了注释。 我不明白的是,我如何编辑上述函数以循环通过“门户”,并检查门户名称“pn”和“tn”是否包含值(不管值是什么),以及检查附加名称“tm”是否不包含值99999999,以及上述是否全部为“true”,然后获取x和y值并使用它们绘制入口,并循环ofc以绘制其余入口

我已经有了draw函数,还有什么没有,我只是不知道如何循环使用发布的XML代码,检查某些名称和值(pn&tn&tm),然后在满足条件的情况下获取x和y,最后在draw函数中使用它并重复,直到什么都没有留下


我希望您能理解这一点,谢谢。

既然您选择了linq to xml,这将非常简单。基本上,你可以使用
Elements()
来切碎东西,直到你得到你想要的,或者拿出一些炸药,然后使用
subjects()
。混乱的程度完全取决于你。我将使用
Elements()
方法。但是
subjects()
调用在语法上几乎相同,但在这种情况下过滤的数量大致相同

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

IEnumerable data=doc.Elements(“imgdir”)。其中(el=>el.HasAttributes)

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

对于所有获得需要传递的数据的各种方法,只需编写另一个查询来限制更多的内容。在本例中,您可以使用以下方法:

XElement portal=data.Elements().SingleOrDefault(el=>el.Attribute(“name”).Value==“portal”)

现在您有了一个可以进一步拆分的
XElement
。获取最精细的
imgdir
s的时间:

IEnumerable 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
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.");
}

将异常放在其中是一种很好的做法,因为此方法可能会在您的程序上下文中重用,并且如果其他开发人员误用它,它会指出问题。

我需要查看门户中的pn和tn是否有值(除空白/空以外的任何值)如果tm不等于99999999,如果是,则获取x和y值。否则,我将尝试使用你给我的东西。你说它是一个较小的东西是什么意思?我用“大”和“小”来表示行数的差异。基本上,1、4和6都包含pn、tn和tm中的数据,而不是0、2、3和5。我确实在那里测试了代码,因此您可能可以将其复制并粘贴到适当的位置。基本上,当您使用条件语句时,只需分别调用
getPortalXY
getWidth
来替换注释。作为一个需要考虑的设计,您可以使用这些方法来接受<代码> xBase<代码>,而不是所有的<代码> int <代码> > s和<代码>字符串< /代码> s。我将更新答案,以包括对
getWidth
的重写,这将使您在使用linq to xml时处于更好的地位。我刚刚回来,注意到您发布了一个通用函数来获取整数(假设名称的值)!仅供参考,getWidth与问题完全无关;不过,我感谢您的样本重写!因此,我不需要使用4个单独的函数(除了值*ex.getHeight、getCenterX等之外,所有函数都包含与getWidth相同的代码),而只需加载xml一次,然后使用您的示例重写?另外,对于您以前的代码(在编辑之前),我可以将另一个if函数放在if for tn&tm中,对吗?谢谢,我很欣赏这一点,因为我通常不擅长XML。
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.");
}