我尝试通过此链接解析xml文件:http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.quakeml。
我遇到的问题是foreach
循环本身没有执行。我认为这是xml文档中名称空间的问题。
以下是我的代码:
protected void btnStoreXMLData_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["EarthquakeCS"].ConnectionString);
SqlCommand cmd = new SqlCommand();
try
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(Server.MapPath("~/App_Data/all_hour.xml"));
XmlNamespaceManager nmspc = new XmlNamespaceManager(xmlDoc.NameTable);
nmspc.AddNamespace("", "http://quakeml.org/xmlns/bed/1.2");
nmspc.AddNamespace("catalog", "http://anss.org/xmlns/catalog/0.1");
nmspc.AddNamespace("q", "http://quakeml.org/xmlns/quakeml/1.2");
XmlNodeList dataNodes = xmlDoc.SelectNodes("/quakeml/eventParameters/event", nmspc);
//ScriptManager.RegisterStartupScript(this, this.GetType(), "Message", "alert('test0');", true);
foreach (XmlNode node in dataNodes)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "Message", "alert('test1');", true);
string location = (node.SelectSingleNode("description/text") != null) ? node.SelectSingleNode("description/text").InnerText.ToString() : string.Empty;
string time = (node.SelectSingleNode("origin/time/value") != null) ? node.SelectSingleNode("origin/time/value").InnerText.ToString() : string.Empty;
string longitude = (node.SelectSingleNode("origin/longitude/value") != null) ? node.SelectSingleNode("origin/longitude/value").InnerText.ToString() : string.Empty;
string latitude = (node.SelectSingleNode("origin/latitude/value") != null) ? node.SelectSingleNode("origin/latitude/value").InnerText.ToString() : string.Empty;
string depth = (node.SelectSingleNode("origin/depth/value") != null) ? node.SelectSingleNode("origin/depth/value").InnerText.ToString() : string.Empty;
string magnitude = (node.SelectSingleNode("magnitude/mag/value") != null) ? node.SelectSingleNode("magnitude/mag/value").InnerText.ToString() : string.Empty;
string magnitudeType = (node.SelectSingleNode("magnitude/type/") != null) ? node.SelectSingleNode("magnitude/type/").InnerText.ToString() : string.Empty;
cmd.CommandText = "INSERT INTO tblEarthquake (Location,Time,Latitude,Longitude,Depth,Magnitude,MagnitudeType) "
+ "VALUES (@Location,@Time,@Latitude,@Longitude,@Depth,@Magnitude,@MagnitudeType)";
cmd.CommandType = CommandType.Text;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@Location", location);
cmd.Parameters.AddWithValue("@Time", time);
cmd.Parameters.AddWithValue("@Latitude", latitude);
cmd.Parameters.AddWithValue("@Longitude", longitude);
cmd.Parameters.AddWithValue("@Depth", depth);
cmd.Parameters.AddWithValue("@Magnitude", magnitude);
cmd.Parameters.AddWithValue("@MagnitudeType", magnitudeType);
cmd.Connection = con;
if (con.State == ConnectionState.Closed)
{
con.Open();
}
int result = cmd.ExecuteNonQuery();
if (result > 0)
{
//XML data has been inserted
}
else
{
//XML data has not been inserted
}
}
}
catch (Exception ex)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "Message", "alert('Error occured : " + ex.Message.ToString() + "');", true);
return;
}
finally
{
con.Close();
cmd.Dispose();
}
}`
答案 0 :(得分:2)
您已经填充了NamespaceManager,但您没有使用任何
快速浏览一下,建议您至少应指出根位于q:
。粗略地,未经测试:
// ... xmlDoc.SelectNodes("/quakeml/eventParameters/event", nmspc);
... xmlDoc.SelectNodes("/q:quakeml/eventParameters/event", nmspc);
PS:使用XElement类,使用命名空间和XML通常会容易得多。值得研究。
答案 1 :(得分:2)
改变这个:
nmspc.AddNamespace("", "http://quakeml.org/xmlns/bed/1.2");
对此:
nmspc.AddNamespace("def", "http://quakeml.org/xmlns/bed/1.2");
您的查询应更改为以下内容:
/q:quakeml/def:eventParameters/def:event
为什么需要这个改变?关于这个问题的答案,请看一个很好的解释here。但正如其他人所说,与XDocument
合作更好,它更新更容易。
编辑循环中修改后的查询:
string location = (node.SelectSingleNode("./def:description/def:text", nmspc) != null) ? node.SelectSingleNode("./def:description/def:text", nmspc).InnerText.ToString() : string.Empty;
string time = (node.SelectSingleNode("./def:origin/def:time/def:value", nmspc) != null) ? node.SelectSingleNode("./def:origin/def:time/def:value", nmspc).InnerText.ToString() : string.Empty;
string longitude = (node.SelectSingleNode("./def:origin/def:longitude/def:value", nmspc) != null) ? node.SelectSingleNode("./def:origin/def:longitude/def:value", nmspc).InnerText.ToString() : string.Empty;
string latitude = (node.SelectSingleNode("./def:origin/def:latitude/def:value", nmspc) != null) ? node.SelectSingleNode("./def:origin/def:latitude/def:value", nmspc).InnerText.ToString() : string.Empty;
string depth = (node.SelectSingleNode("./def:origin/depth/def:value", nmspc) != null) ? node.SelectSingleNode("./def:origin/def:depth/def:value", nmspc).InnerText.ToString() : string.Empty;
string magnitude = (node.SelectSingleNode("./def:magnitude/def:mag/def:value", nmspc) != null) ? node.SelectSingleNode("./def:magnitude/def:mag/def:value", nmspc).InnerText.ToString() : string.Empty;
string magnitudeType = (node.SelectSingleNode("./def:magnitude/def:type", nmspc) != null) ? node.SelectSingleNode("./def:magnitude/def:type", nmspc).InnerText.ToString() : string.Empty;
答案 2 :(得分:0)
我建议你使用linq到xml它更容易:
XElement xmlDoc = XElement.Load(Server.MapPath("~/App_Data/all_hour.xml"));
var dataNodes = xmlDoc.Descendants().Where(s => s.Name.LocalName == "event");
答案 3 :(得分:0)
我更喜欢使用XElement / XDoc而不是XMLElement& Co因为这更容易。
基本上,您的查询返回0个元素,因为您不使用名称空间。
所以foreach没有要解析的集合。
您可以执行类似
的操作using System.Xml.Linq; //to use XElement XDoc etc
XDocument xDoc = new XDocument ();
XDocument doc = XDocument.Parse ( xmlIn ); -> xmlIn contains your XML code to parse as string
//即获取所有带有事件的节点(不考虑ns) var result = doc.Descendants()。Where(s => s.Name.LocalName ==" event"); foreach(结果中的var项) { Debug.WriteLine(item.Value); }
或使用命名空间
var result = doc.Descendants ().Where ( s => s.Name.LocalName == "event"
&&
s.Name.NameSpaceName == "myNamespace");
HTH
答案 4 :(得分:0)
如果您可以使用LinqToXml和XDocument,这会容易得多。
var document = XDocument.Load("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.quakeml");
XNamespace rNs = "http://quakeml.org/xmlns/bed/1.2";
var events = document.Root.Descendants(rNs + "eventParameters").Elements(rNs + "event");
foreach (var ev in events)
{
var location = ev.Descendants(rNs + "description").Descendants(rNs + "text").Single().Value;
var originElement = ev.Descendants(rNs + "origin");
var time = originElement.Descendants(rNs + "time").Descendants(rNs + "value").Single().Value;
var longitude = originElement.Descendants(rNs + "longitude").Descendants(rNs + "value").Single().Value;
var latitude = originElement.Descendants(rNs + "latitude").Descendants(rNs + "value").Single().Value;
var depth = originElement.Descendants(rNs + "depth").Descendants(rNs + "value").Single().Value;
var magnitudeElement = ev.Descendants(rNs + "magnitude");
var magnitude = magnitudeElement.Descendants(rNs + "mag").Descendants(rNs + "value").Single().Value;
var magnitudeType = magnitudeElement.Descendants(rNs + "type").Single().Value;
}