现有节点的 XDocument 属性不存在
XDocument attribute of existing node does not exist
我正在从 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 中除文本之外的唯一差异是 OWNED_PROPERTY 标签位于附加标签下,而直接位于 .但是正如您所看到的,我的代码跳过了标记,因为它对我的目的毫无用处。
好的,所以您的变量名称是 clsxl
、clxll
、clxl
、chicxulub
、mxyzptlk
和 lerxst
。足够明智。
这一行抛出异常。某处迷失在该表达式的深处,某些东西正在返回 null。好吧,您不能通过将整个内容粘贴到对 MessageBox.Show()
的调用的括号之间来调试它,因为重点是它抛出异常而不是返回值。
//System.Windows.Forms.MessageBox.Show(clsxl.Element(ns + "COLLATERAL").Attribute("SequenceNumber").Value.ToString());
cseqnum = int.Parse(clsxl.Element(ns + "COLLATERAL").Attribute("SequenceNumber").Value.ToString());
这是您要做的:将其分解为尽可能最简单的表达式,然后查看 returns 是什么。需要一段时间,但阅读所有那些抱怨变量声明的人的评论也是如此。
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 个字符时,那些非常紧凑的 70 年代 C 风格标识符是一个合理的妥协,但我们现在都有更大的屏幕。
您的 XML 文档有一个默认名称空间,因此所有导航操作都必须使用它。您在大多数地方都做对了,但是您在以下行中缺少名称空间:
bool bv = resx.Descendants("COLLATERAL")
我正在从 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 中除文本之外的唯一差异是 OWNED_PROPERTY 标签位于附加标签下,而直接位于 .但是正如您所看到的,我的代码跳过了标记,因为它对我的目的毫无用处。
好的,所以您的变量名称是 clsxl
、clxll
、clxl
、chicxulub
、mxyzptlk
和 lerxst
。足够明智。
这一行抛出异常。某处迷失在该表达式的深处,某些东西正在返回 null。好吧,您不能通过将整个内容粘贴到对 MessageBox.Show()
的调用的括号之间来调试它,因为重点是它抛出异常而不是返回值。
//System.Windows.Forms.MessageBox.Show(clsxl.Element(ns + "COLLATERAL").Attribute("SequenceNumber").Value.ToString());
cseqnum = int.Parse(clsxl.Element(ns + "COLLATERAL").Attribute("SequenceNumber").Value.ToString());
这是您要做的:将其分解为尽可能最简单的表达式,然后查看 returns 是什么。需要一段时间,但阅读所有那些抱怨变量声明的人的评论也是如此。
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 个字符时,那些非常紧凑的 70 年代 C 风格标识符是一个合理的妥协,但我们现在都有更大的屏幕。
您的 XML 文档有一个默认名称空间,因此所有导航操作都必须使用它。您在大多数地方都做对了,但是您在以下行中缺少名称空间:
bool bv = resx.Descendants("COLLATERAL")