我从Web服务中提取XML集,将其加载到XDocument中然后解析出来。在一个节点上,如果我将XML输出到文件,那么该属性是明确的,它告诉我它不存在。我无法弄清楚我正在做些什么导致这个错误。
<?xml version="1.0" encoding="utf-8"?>
<MESSAGE xmlns="http://www.mismo.org/residential/2009/schemas_v1_4_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<DEAL_SETS>
<DEAL_SET>
<DEALS>
<DEAL>
<ASSETS>
<OWNED_PROPERTIES>
<OWNED_PROPERTY SequenceNumber="1">
<OWNED_PROPERTY_DETAIL>
<PropertyUsageType>PrimaryResidence</PropertyUsageType>
</OWNED_PROPERTY_DETAIL>
</OWNED_PROPERTY>
<OWNED_PROPERTY SequenceNumber="2">
<OWNED_PROPERTY_DETAIL>
<PropertyUsageType>PrimaryResidence</PropertyUsageType>
</OWNED_PROPERTY_DETAIL>
</OWNED_PROPERTY>
</OWNED_PROPERTIES>
</ASSETS>
<COLLATERALS>
<COLLATERAL SequenceNumber="1">
<COLLATERAL_DETAIL>
<LienPriorityExceptionType>FirstLien</LienPriorityExceptionType>
</COLLATERAL_DETAIL>
<PROPERTIES>
<PROPERTY>
<FLOOD_DETERMINATION>
<FLOOD_DETERMINATION_DETAIL/>
</FLOOD_DETERMINATION>
<IMPROVEMENT>
<UNIT_GROUPS>
<UNIT_GROUP>
<UNIT_GROUP_DETAIL>
<UnitType>UnitOne</UnitType>
</UNIT_GROUP_DETAIL>
<ROOM_TYPE_SUMMARY/>
</UNIT_GROUP>
</UNIT_GROUPS>
</IMPROVEMENT>
</PROPERTY>
</PROPERTIES>
</COLLATERAL>
<COLLATERAL SequenceNumber="5">
<COLLATERAL_DETAIL>
<LienPriorityExceptionType>FirstLien</LienPriorityExceptionType>
</COLLATERAL_DETAIL>
<PROPERTIES>
<PROPERTY>
<FLOOD_DETERMINATION>
<FLOOD_DETERMINATION_DETAIL/>
</FLOOD_DETERMINATION>
<IMPROVEMENT>
<UNIT_GROUPS>
<UNIT_GROUP>
<UNIT_GROUP_DETAIL>
<UnitType>UnitOne</UnitType>
</UNIT_GROUP_DETAIL>
<ROOM_TYPE_SUMMARY/>
</UNIT_GROUP>
</UNIT_GROUPS>
</IMPROVEMENT>
</PROPERTY>
</PROPERTIES>
</COLLATERAL>
</COLLATERALS>
</DEAL>
</DEALS>
</DEAL_SET>
</DEAL_SETS>
</MESSAGE>
我的代码可以很好地找到OWNED_PROPERTY的SequenceNumber值,但在COLLATERAL上爆炸:
using System.Xml;
using System.Xml.Linq;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Collections.Generic;
XDocument resx = new XDocument();
public override void MethodInternal()
{
string uid = "something";
string pwd = "somethingelse";
string httppath = "url";
try
{
NetworkCredential cred = new NetworkCredential(uid, pwd);
CredentialCache credCache = new CredentialCache();
credCache.Add(new Uri(httppath), "NTLM", cred);
WebRequest client = WebRequest.Create(httppath);
client.Credentials = credCache;
client.Method = "GET";
client.ContentType = "application/xml";
WebResponse resp = client.GetResponse();
Stream respStream = resp.GetResponseStream();
StreamReader strrdr = new StreamReader(respStream);
string allxml = strrdr.ReadToEnd();
byte[] byteArray = Encoding.UTF8.GetBytes(fullstr);
XNamespace ns = "http://www.mismo.org/residential/2009/schemas_v1_4_2";
resx = XDocument.Parse(allxml);
strrdr.Close();
respStream.Close();
resp.Close();
int seqnum = 0;
int cseqnum = 0;
foreach (XElement b in resx.Root.Descendants(ns + "DEAL"))
{
// Primary node: ASSETS
if (b.Elements(ns + "ASSETS").Any())
{
IEnumerable<XElement> axl = b.Descendants(ns + "ASSETS");
foreach (var axcol in axl.Elements())
{
seqnum = 0;
IEnumerable<XElement> opxl = b.Descendants(ns + "OWNED_PROPERTY");
foreach (var opxlcol in axl.Elements())
{
seqnum = int.Parse(opxlcol.Element(ns + "OWNED_PROPERTY").Attribute("SequenceNumber").Value.ToString());
IEnumerable<XElement> opxls = opxlcol.Descendants(ns + "OWNED_PROPERTY");
foreach (var opxlsc in opxls.Elements())
{
if (opxlsc.Elements(ns + "PropertyUsageType").Any())
//occa.Add(seqnum, opxlsc.Element(ns + "PropertyUsageType").Value.ToString());
}
} // OWNED_PROPERTY XElements
} // XElements under ASSETS
} // test to make sure ASSETS exists
// Primary node: COLLATERALS
if (b.Elements(ns + "COLLATERALS").Any())
{
IEnumerable<XElement> colsxl = b.Descendants(ns + "COLLATERALS");
foreach (var clsxl in colsxl.Elements())
{
cseqnum = 0;
IEnumerable<XElement> clxl = clsxl.DescendantsAndSelf(ns + "COLLATERAL");
foreach (var clxll in clxl.Elements())
{
//System.Windows.Forms.MessageBox.Show(ns.ToString() + clsxl.Name.LocalName.ToString());
//if (clsxl.Name.LocalName.ToString() == "COLLATERAL")
//{
bool bv = resx.Descendants("COLLATERAL").Select(x => (int?)x.Attribute("SequenceNumber")).FirstOrDefault(x => x != null) > 0;
System.Windows.Forms.MessageBox.Show(bv.ToString());
System.Windows.Forms.MessageBox.Show(clsxl.Element(ns + "COLLATERAL").Attribute("SequenceNumber").Value.ToString());
cseqnum = int.Parse(clsxl.Element(ns + "COLLATERAL").Attribute("SequenceNumber").Value.ToString());
//}
if (clxll.Elements(ns + "LienPropertyExceptionType").Any())
//liena.Add(cseqnum, clxll.Element(ns + "LienPropertyExceptionType").Value.ToString());
IEnumerable<XElement> pxl = clsxl.Descendants(ns + "PROPERTY");
foreach (var p in pxl.Elements())
{
if (p.Elements(ns + "IMPROVEMENT").Any())
{
IEnumerable<XElement> ig = p.Descendants(ns + "IMPROVEMENT");
foreach (var igxl in ig.Elements())
{
if (igxl.Elements(ns + "UnitType").Any())
//nua.Add(cseqnum, igxl.Element(ns + "UnitType").Value.ToString());
//} // XElements under UNIT_GROUP_DETAIL
} // XElements under IMPROVEMENT
} // test to make sure IMPROVEMENT exists
} // XElements under PROPERTY
} // XElements in COLLATERAL
} // XElements under COLLATERALS
} // test to make sure COLLATERALS exists
} // root
}
catch (Exception ex)
{
//handle exception
}
}
那我哪里错了?除了XML中的textual之外,唯一的差异是OWNED_PROPERTY标记位于附加标记下,而正好位于其下方。但正如你所看到的那样,我的代码正在跳过标记,因为它对我的目的来说是无用的。
答案 0 :(得分:2)
好的,您的变量名称为clsxl
,clxll
,clxl
,chicxulub
,mxyzptlk
和lerxst
。足够明智。
这一行引发了一个例外。某个地方在某个表达的深处迷失了,某些东西正在返回null。好吧,你不能通过在调用MessageBox.Show()
的parens之间粘贴整个事件来调试它,因为整个点是抛出异常而不是返回值。
//System.Windows.Forms.MessageBox.Show(clsxl.Element(ns + "COLLATERAL").Attribute("SequenceNumber").Value.ToString());
cseqnum = int.Parse(clsxl.Element(ns + "COLLATERAL").Attribute("SequenceNumber").Value.ToString());
这就是你要做的事情:将其分解为最简单的表达式,看看会返回什么。需要一段时间,但阅读那些抱怨变量声明的人的评论也是如此。
var element = clsxl.Element(ns + "COLLATERAL");
var attr = element.Attribute("SequenceNumber");
// attr.Value is already a string. If it's anything.
cseqnum = int.Parse(attr.Value);
在第一行上设置断点,然后将鼠标悬停在所有行上。
你会发现clsxl
是“COLLATERAL”。它没有名为“COLLATERAL”且具有“SequenceNumber”属性的子项。 它具有“SequenceNumber”属性。
// Ain't no such animal
var element = clsxl.Element(ns + "COLLATERAL");
clsxl
是父循环变量。这是“COLLATERAL”。这就是你想要的那个。
var attr = clsxl.Attribute("SequenceNumber");
cseqnum = int.Parse(attr.Value);
我有一种直觉,你可能会失去50%的代码并且睡得更轻松,但我没有尝试梳理每一点点的意图,所以这可能是一个很高的估计。
严肃地说,我确实知道你从哪里得到这些名字。它们不是噪音,它们基于XML元素名称。但是,我会称他们为xnCollateral
,依此类推。额外的打字付出了代价。当我们在VT100上有80x25个字符时,那些非常紧凑的'70s C风格标识符是一个合理的折衷方案,但我们现在都拥有更大的屏幕。
答案 1 :(得分:0)
您的XML文档具有默认命名空间,因此所有导航操作都必须使用它。您在大多数地方都做得很好,但是您在以下行中错过了命名空间:
bool bv = resx.Descendants("COLLATERAL")