如何正确处理这个 XML 响应 (SOAP:Envelope)?
How to handle this XML response (SOAP:Envelope) correctly?
我向我们公司的 HP 服务经理创建了一个 Web 请求,以收集一些数据。
结果是:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<RetrieveSuegChangeListResponse message="Success" returnCode="0" schemaRevisionDate="2015-04-22" schemaRevisionLevel="0" status="SUCCESS" xsi:schemaLocation="http://schemas.hp.com/SM/7 http://servicemanager-ws.intranet.example.com:12345/SM/7/SuegChange.xsd" xmlns="http://schemas.hp.com/SM/7" xmlns:cmn="http://schemas.hp.com/SM/7/Common" xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<instance query="" recordid="CM00088641 - Server: Migration of the SSH-HOP" uniquequery="header,number="CM00088641"">
<header type="Structure">
<Number type="String">CM00088641</Number>
<PlannedStart type="DateTime">2015-07-06T06:00:00+00:00</PlannedStart>
<PlannedEnd type="DateTime">2015-07-06T18:00:00+00:00</PlannedEnd>
<Title type="String">Server: Migration of the SSH-HOP</Title>
</header>
<middle type="Structure">
<AffectedCi type="Array">
<AffectedCi type="String">SERVER1</AffectedCi>
<AffectedCi type="String">SERVER2</AffectedCi>
<AffectedCi type="String">SERVER3</AffectedCi>
</AffectedCi>
</middle>
</instance>
</RetrieveSuegChangeListResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
现在我正尝试从此结果中获取信息,但我在使用以下 C# 代码时遇到了麻烦:
public static string gettextfromWebserviceChange()
{
#region suchen im XML
XmlDocument objReturn = new XmlDocument();
string result = @"<SOAP-ENV:Envelope xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/"">
<SOAP-ENV:Body>
<RetrieveSuegChangeListResponse message=""Success"" returnCode=""0"" schemaRevisionDate=""2015-04-22"" schemaRevisionLevel=""0"" status=""SUCCESS"" xsi:schemaLocation=""http://schemas.hp.com/SM/7 http://servicemanager-ws.intranet.example.com:12345/SM/7/SuegChange.xsd"" xmlns=""http://schemas.hp.com/SM/7"" xmlns:cmn=""http://schemas.hp.com/SM/7/Common"" xmlns:xmime=""http://www.w3.org/2005/05/xmlmime"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
<instance query="" recordid=""CM00088641 - Server: Migration of the SSH-HOP"" uniquequery=""header,number="CM00088641""">
<header type=""Structure"">
<Number type=""String"">CM00088641</Number>
<PlannedStart type=""DateTime"">2015-07-06T06:00:00+00:00</PlannedStart>
<PlannedEnd type=""DateTime"">2015-07-06T18:00:00+00:00</PlannedEnd>
<Title type=""String"">Server: Migration of the SSH-HOP</Title>
</header>
<middle type=""Structure"">
<AffectedCi type=""Array"">
<AffectedCi type=""String"">SERVER1</AffectedCi>
<AffectedCi type=""String"">SERVER2</AffectedCi>
<AffectedCi type=""String"">SERVER3</AffectedCi>
</AffectedCi>
</middle>
</instance>
</RetrieveSuegChangeListResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>";
objReturn.LoadXml(result);
List<String> ListAffectedCi = new List<string>();
String Descriptiontxt = "";
String ChangeStartDate = "";
String ChangeEndDate = "";
StringBuilder builder = new StringBuilder();
//ToDo: which is the right NameSpace!!!!!!!!!
XmlNamespaceManager namespaces = new XmlNamespaceManager(objReturn.NameTable);
namespaces.AddNamespace("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
//XmlNode idNode = doc.SelectSingleNode("/My_RootNode/ns:id", namespaces);
XmlNodeList xnList = objReturn.GetElementsByTagName("header");
foreach (XmlNode xn in xnList)
{
ChangeStartDate = xn["PlannedStart"].InnerText;
ChangeEndDate = xn["PlannedEnd"].InnerText;
Descriptiontxt = xn["Title"].InnerText.Trim();
}
XmlNodeList xnList2 = objReturn.GetElementsByTagName("AffectedCi");
int i = 1;// xnList2.Count;
foreach (XmlNode xn in xnList2)
{
// here i'm get in trouble...
ListAffectedCi.Add(xn["AffectedCi"].InnerText);
}
#endregion
#region zusammenbau des strings
/////////////////
// Append a string to the StringBuilder and then another line break.
builder.Append("<b>Title :</b> " + Descriptiontxt + "<br />");
builder.Append("<b>Resource :</b> " + String.Join(", ", ListAffectedCi) + "<br />");
DateTime _ChangeStartDate = DateTime.Parse(ChangeStartDate, null, System.Globalization.DateTimeStyles.RoundtripKind);
DateTime _ChangeEndDate = DateTime.Parse(ChangeEndDate, null, System.Globalization.DateTimeStyles.RoundtripKind);
TimeSpan span = _ChangeEndDate.Subtract ( _ChangeStartDate );
//"yyyy-MM-ddTHH:mm:ss.fff"
builder.Append("<b>Dauer :</b> " + _ChangeStartDate.ToString("dd.MM.yyyy HH:mm:ss") + " - " + " " + _ChangeEndDate.ToString("dd.MM.yyyy HH:mm:ss") + "<br />");
builder.Append("<b>Zeitspanne :</b> " + span.Days + " Tage und " + span.Hours + " Stunden.<br />");
//builder.Append("<dl><dt><b>Zeitspanne :</b></dt><dd>" + span.Days + " Tage</dd><dd>" + span.Hours + " Stunden</dd><dd>" + span.Minutes + " Minuten</dd><dd>" + span.Seconds + " Sekunden</dd><dd>" + span.Ticks + " Ticks</dd></dl>");
#endregion
return builder.ToString();
}
我的问题是,我收到一个包含 4 个 AffectedCI 的列表...3 个已填充,一个为空,这会创建一个未处理的 NullReferenceException。
有谁知道如何处理好这个 XML?
我也尝试过使用 Xpath...但是我很愚蠢地为那个找到正确的命名空间 XML...否则我可以直接转到 AffectedCI 路径以获得正确数量的CI...
希望有人能帮助我!
先感谢您,
最好的问候
如果您不喜欢 XmlDocument
,LINQ to XML 是一个更好的解决方案:
XNamespace ns = "http://schemas.hp.com/SM/7";
var doc = XDocument.Parse(result);
var header = doc.Descendants(ns + "header").Single();
var start = (DateTime)header.Element(ns + "PlannedStart");
var end = (DateTime)header.Element(ns + "PlannedEnd");
var description = (string)header.Element(ns + "Title");
var affectedCis = doc.Descendants(ns + "AffectedCi")
.Where(e => (string)e.Attribute("type") == "String")
.Select(e => e.Value)
.ToList();
我向我们公司的 HP 服务经理创建了一个 Web 请求,以收集一些数据。 结果是:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<RetrieveSuegChangeListResponse message="Success" returnCode="0" schemaRevisionDate="2015-04-22" schemaRevisionLevel="0" status="SUCCESS" xsi:schemaLocation="http://schemas.hp.com/SM/7 http://servicemanager-ws.intranet.example.com:12345/SM/7/SuegChange.xsd" xmlns="http://schemas.hp.com/SM/7" xmlns:cmn="http://schemas.hp.com/SM/7/Common" xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<instance query="" recordid="CM00088641 - Server: Migration of the SSH-HOP" uniquequery="header,number="CM00088641"">
<header type="Structure">
<Number type="String">CM00088641</Number>
<PlannedStart type="DateTime">2015-07-06T06:00:00+00:00</PlannedStart>
<PlannedEnd type="DateTime">2015-07-06T18:00:00+00:00</PlannedEnd>
<Title type="String">Server: Migration of the SSH-HOP</Title>
</header>
<middle type="Structure">
<AffectedCi type="Array">
<AffectedCi type="String">SERVER1</AffectedCi>
<AffectedCi type="String">SERVER2</AffectedCi>
<AffectedCi type="String">SERVER3</AffectedCi>
</AffectedCi>
</middle>
</instance>
</RetrieveSuegChangeListResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
现在我正尝试从此结果中获取信息,但我在使用以下 C# 代码时遇到了麻烦:
public static string gettextfromWebserviceChange()
{
#region suchen im XML
XmlDocument objReturn = new XmlDocument();
string result = @"<SOAP-ENV:Envelope xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/"">
<SOAP-ENV:Body>
<RetrieveSuegChangeListResponse message=""Success"" returnCode=""0"" schemaRevisionDate=""2015-04-22"" schemaRevisionLevel=""0"" status=""SUCCESS"" xsi:schemaLocation=""http://schemas.hp.com/SM/7 http://servicemanager-ws.intranet.example.com:12345/SM/7/SuegChange.xsd"" xmlns=""http://schemas.hp.com/SM/7"" xmlns:cmn=""http://schemas.hp.com/SM/7/Common"" xmlns:xmime=""http://www.w3.org/2005/05/xmlmime"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
<instance query="" recordid=""CM00088641 - Server: Migration of the SSH-HOP"" uniquequery=""header,number="CM00088641""">
<header type=""Structure"">
<Number type=""String"">CM00088641</Number>
<PlannedStart type=""DateTime"">2015-07-06T06:00:00+00:00</PlannedStart>
<PlannedEnd type=""DateTime"">2015-07-06T18:00:00+00:00</PlannedEnd>
<Title type=""String"">Server: Migration of the SSH-HOP</Title>
</header>
<middle type=""Structure"">
<AffectedCi type=""Array"">
<AffectedCi type=""String"">SERVER1</AffectedCi>
<AffectedCi type=""String"">SERVER2</AffectedCi>
<AffectedCi type=""String"">SERVER3</AffectedCi>
</AffectedCi>
</middle>
</instance>
</RetrieveSuegChangeListResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>";
objReturn.LoadXml(result);
List<String> ListAffectedCi = new List<string>();
String Descriptiontxt = "";
String ChangeStartDate = "";
String ChangeEndDate = "";
StringBuilder builder = new StringBuilder();
//ToDo: which is the right NameSpace!!!!!!!!!
XmlNamespaceManager namespaces = new XmlNamespaceManager(objReturn.NameTable);
namespaces.AddNamespace("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
//XmlNode idNode = doc.SelectSingleNode("/My_RootNode/ns:id", namespaces);
XmlNodeList xnList = objReturn.GetElementsByTagName("header");
foreach (XmlNode xn in xnList)
{
ChangeStartDate = xn["PlannedStart"].InnerText;
ChangeEndDate = xn["PlannedEnd"].InnerText;
Descriptiontxt = xn["Title"].InnerText.Trim();
}
XmlNodeList xnList2 = objReturn.GetElementsByTagName("AffectedCi");
int i = 1;// xnList2.Count;
foreach (XmlNode xn in xnList2)
{
// here i'm get in trouble...
ListAffectedCi.Add(xn["AffectedCi"].InnerText);
}
#endregion
#region zusammenbau des strings
/////////////////
// Append a string to the StringBuilder and then another line break.
builder.Append("<b>Title :</b> " + Descriptiontxt + "<br />");
builder.Append("<b>Resource :</b> " + String.Join(", ", ListAffectedCi) + "<br />");
DateTime _ChangeStartDate = DateTime.Parse(ChangeStartDate, null, System.Globalization.DateTimeStyles.RoundtripKind);
DateTime _ChangeEndDate = DateTime.Parse(ChangeEndDate, null, System.Globalization.DateTimeStyles.RoundtripKind);
TimeSpan span = _ChangeEndDate.Subtract ( _ChangeStartDate );
//"yyyy-MM-ddTHH:mm:ss.fff"
builder.Append("<b>Dauer :</b> " + _ChangeStartDate.ToString("dd.MM.yyyy HH:mm:ss") + " - " + " " + _ChangeEndDate.ToString("dd.MM.yyyy HH:mm:ss") + "<br />");
builder.Append("<b>Zeitspanne :</b> " + span.Days + " Tage und " + span.Hours + " Stunden.<br />");
//builder.Append("<dl><dt><b>Zeitspanne :</b></dt><dd>" + span.Days + " Tage</dd><dd>" + span.Hours + " Stunden</dd><dd>" + span.Minutes + " Minuten</dd><dd>" + span.Seconds + " Sekunden</dd><dd>" + span.Ticks + " Ticks</dd></dl>");
#endregion
return builder.ToString();
}
我的问题是,我收到一个包含 4 个 AffectedCI 的列表...3 个已填充,一个为空,这会创建一个未处理的 NullReferenceException。 有谁知道如何处理好这个 XML?
我也尝试过使用 Xpath...但是我很愚蠢地为那个找到正确的命名空间 XML...否则我可以直接转到 AffectedCI 路径以获得正确数量的CI...
希望有人能帮助我! 先感谢您, 最好的问候
如果您不喜欢 XmlDocument
,LINQ to XML 是一个更好的解决方案:
XNamespace ns = "http://schemas.hp.com/SM/7";
var doc = XDocument.Parse(result);
var header = doc.Descendants(ns + "header").Single();
var start = (DateTime)header.Element(ns + "PlannedStart");
var end = (DateTime)header.Element(ns + "PlannedEnd");
var description = (string)header.Element(ns + "Title");
var affectedCis = doc.Descendants(ns + "AffectedCi")
.Where(e => (string)e.Attribute("type") == "String")
.Select(e => e.Value)
.ToList();