我有一个解析XML输入文件的程序。 XML有点被破坏了。我没有开发模式,也没有控制生成XML的程序。以下是我遇到问题的XML示例。
<object type="vdisk" >
<property name="mdisk_grp_id" value="many" />
<property name="mdisk_grp_name" value="many" />
<property name="mdisk_grp_id" value="10" />
<property name="mdisk_grp_name" value="VMAX5161" />
</object>
问题是同名的多个属性。显然这是不正确的。我需要选择没有“很多”作为值的那个。现在我的程序抓住了它,因为它首先发生。它破坏了程序中的其他内容。以下是我尝试过的内容。这是我的VDisk类的构造函数的部分列表。它似乎适用于输入文件中“vdisk”类型的某些对象,但不适用于其他对象。
public VDisk(XElement element)
{
var mdg = from mdgs in element.Descendants("property")
where
mdgs.Attribute("name").Value == "mdisk_grp_name"
select mdgs;
foreach (XElement mdgp in mdg)
{
if (mdgp.Attribute("value").Value != "many")
{
MDiskGrpName = mdgp.Attribute("value").Value;
break;
}
}
}
这是抛出异常的代码。没有任何实际命名为“many”的MDiskGroup。因此var变回空白。我可以捕获异常并继续,但我想将正确的数据导入VDisk MDiskGroupName属性。
var mdiskgrp = CurrentCluster.MDiskGroups.Where(mdg => mdg.Name == vdisk.MDiskGrpName);
mdiskgrp.FirstOrDefault().VDiskList.Add(vdisk);
答案 0 :(得分:1)
试试这个:
element.Descendants("property").Where(x => x.Attribute("name").Value == "mdisk_grp_name" && x.Attribute("value").Value != "many").First();
答案 1 :(得分:0)
你试图在一个程序中做很多事情。将任务分解为简单任务的管道。如果你想删除除了last之外的给定名称的每个属性,请将其作为预处理转换。它只有几行代码,并且将它分开意味着代码可以重用,因为它可以插入到使用此XML输入的任何管道中,而不是混乱您的“业务”逻辑。转型基本上是这样的:
<xsl:template match="object">
<xsl:copy>
<xsl:copy select="@*"/>
<xsl:for-each-group select="Property" group-by="@name">
<xsl:copy-of select="current-group()[last()]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>