【问题标题】:Using XmlNodeList with several web services call将 XmlNodeList 与多个 Web 服务调用一起使用
【发布时间】:2015-12-14 18:32:12
【问题描述】:

我正在构建一个调用 3 个不同 Web 服务的控制台应用程序。第一个调用所有项目及其项目 ID、项目状态和项目名称。

第一个 Web 服务获取所有项目 ID GetProjectData() 并且调用正确。我将结果放入 csv 文件中。

第二个电话,GetProjectDetails(),它为我提供了所有项目的dataset(数据集中有许多值)。

此调用包含我需要将它放在 GetProjectData() 调用旁边的 projectType(打开或关闭)。

这是来自 GetProjectDetails 数据集调用的架构:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="Table">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="ProjectID" type="xs:string" minOccurs="0" />
              <xs:element name="Title" type="xs:string" minOccurs="0" />
              <xs:element name="ProjectType" type="xs:string" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

我需要获取 ProjectType 并将其分配给我的项目,该项目将显示为打开或关闭。

我创建了一个解析 xml 输出的方法:

public static string parseXML(System.Data.DataSet ds)
{
    string txt = "";
    XmlDocument xml = new XmlDocument();
    xml.LoadXml(ds.GetXml());
    XmlNodeList elements = xml.SelectNodes("/NewDataSet/Table");
    foreach (XmlNode elem in elements)
    {
        txt += elem["ProjectType"].InnerText;
        txt += "\n";
    }
    return txt;

}

我有另一个 Web 服务调用,但我对那个调用是正确的,因为我得到了预期的输出。

问题是我需要将 projecType 提取到最终结果中,并且取决于每个项目类型是打开还是关闭。

这里有我的代码。

string path = @"c:\testList";
try
{                
string List = "listOfProjects";
string outCsvFile = string.Format(@"C:\\testList\\{0}.csv", List + DateTime.Now.ToString("_yyyyMMdd HHmms"));

//This is the call to get all the projects
WS.ProjectData[] pr = db.GetAllProjectData();


using (StreamWriter file = new StreamWriter(fs))
{
file.WriteLine("ProjectID, ProjectTitle,PublishStatus,Type,ProjectStartDate,ProjectEndDate");

    foreach(WS.ProjectMetaData proj in pr.Distinct(new ProjectEqualityComparer()))
    {
        string language = "";
        var userIDs = db.GetList(proj.ProjectID);
        var projectInfo = parseXML(db.GetProjectDetails(language)); //GetProjectDetails require a string into the method

        file.WriteLine("{0},\"{1}\",{2},{3},{4},{5}",       
        proj.ProjectID,
        proj.ProjectTitle,
        proj.PublishStatus,
        userIDs.Length.ToString(NumberFormatInfo.InvariantInfo),
        proj.ProjectStartDate.ToString(DateTimeFormatInfo.InvariantInfo),
        proj.ProjectEndDate.ToString(DateTimeFormatInfo.InvariantInfo),
    }
}

您能帮我将 ProjectType 输出到最终结果中吗? 我想我需要以某种方式对 projectInfo 做一些事情并用 projectIDs 引用它,这样它就可以知道它的类型是打开还是关闭。

谢谢

预期输出:

ProjectID, ProjectTitle, PublishStatus,Type,ProjectStartDate,ProjectEndDate

7bd001b2-991e, "test project", published, open, 01-01-2010, 01-01-2015

4ed00772-541e, "test project 2", expired, Close, 01-01-2010, 01-01-2015

WS.ProjectData[] pr = db.GetAllProjectData(); 里面的内容如下:

ProjectID,
ProjectTitle
PublishStatus
ProjectStartDate
ProjectEndDate

这些是可以从GetAllProjectData()导出的值

数据集还包含 ProjectID,所以如果有办法关联 projectId,那么当它看到相同的 projectID 时,它会分发 ProjectType

我还注意到,如果我从 parseXML 方法内部传递 ProjectID,则数据集中的第一个 ProjectID 会进入每一行的输出(始终相同的 ProjectID) 再次感谢

【问题讨论】:

  • 为什么输出userIDs.Length.ToString(NumberFormatInfo.InvariantInfo)?这不是您要放置Type 的地方吗?
  • 另外,你为什么在循环内调用var projectInfo = parseXML(db.GetProjectDetails(language));?你只是传递一个常量空字符串。
  • @dbc 我需要用户 ID 和类型。 userId 来自 GetList() 网络服务,类型来自 GetProjectDetails() 网络服务,这就是我需要两个结果的原因
  • @dbc GetPtojectDetails() 需要一个字符串作为参数,当我使用 SOAPUI 时,该字符串可以为空。我放入循环中是因为我需要具有相同关系(projectID)的所有输出,谢谢
  • 但是您没有将projectID 传递给db.GetProjectDetails(language),而是传递了一个空字符串。

标签: c# xml dataset console-application streamwriter


【解决方案1】:

我不确定您为什么要费心将DataSet 转换为 XML,然后解析 XML。 DataSet可以直接查询和迭代。

鉴于您为DataSet 显示的架构,要获取所有ProjectType 值的逗号分隔列表,请执行以下操作:

using System.Data; // For System.Data.DataTableExtensions

    var ds = db.GetProjectDetails(language);
    var projectInfo = string.Join(",", ds.Tables["Table"].AsEnumerable().Select(r => r["ProjectType"].ToString()).ToArray());

给定一个string projectId值,要找到它对应的ProjectType,可以使用DataTable.Select()

    string projectId = proj.ProjectID.ToString();
    var ds = db.GetProjectDetails(language);
    var type = var type = ds.Tables["Table"].Select("ProjectId = '" + projectId + "'").Select(r => r["ProjectType"]).SingleOrDefault();
    // Output the type to the file with the rest of the data.

或者,直接使用 Linq Where 过滤器:

using System.Data; // For System.Data.DataTableExtensions

    string projectId = proj.ProjectID.ToString();
    var ds = db.GetProjectDetails(language);
    var type = ds.Tables["Table"].AsEnumerable().Where(r => projectId.Equals(r["ProjectId"])).Select(r => r["ProjectType"]).SingleOrDefault();
    // Output the type to the file with the rest of the data.

【讨论】:

  • 感谢您的回复。我需要将您提供给我的选项放在哪里?进入公共静态字符串 parseXML(System.Data.DataSet ds) 方法?当我尝试将它放在那里时出现错误(并非所有代码路径都返回值)
  • 我进行了更改,但我得到一个错误序列包含多个元素。感谢大家的帮助和支持!
  • @Aarancibia - 这意味着对于给定的项目 ID,DataSet 中有不止一行。在这种情况下你想做什么?另外,您使用的是Select 还是Where 选项?
  • 我工作了!!!!!!!!!!!!!!!!!!多谢!!!你救了我的命!!!谢谢!!!我很感激!
【解决方案2】:

我会这样做 parseXml 方法所以:

static List<string> parseXml(DataSet ds)
{
    List<string> list = new List<string>();

    foreach (DataRow row in ds.Tables[0].Rows)
    {
        list.Add(row["ProjectType"].ToString());
    }

    return list;
}

然后我们做这样的事情:

int counter = 0;

foreach(WS.ProjectMetaData proj in pr.Distinct(new ProjectEqualityComparer()))
{
    // your code here

    var projectInfo = parseXml(ds);

    file.WriteLine("{0},{1}, ... ",
    proj.ProjectID,
    projectInfo[counter],
    // ...
    );

    counter++;
}

【讨论】:

  • 感谢您的回答。当我按照您在 var projectInfo = parseXml(ds);它说 ds 在当前上下文中不存在
  • 注意大小写。我将方法 parseXML 重命名为 parseXml 以符合普遍接受的命名约定。
  • 对不起,我还有一个问题。它可以工作,但输出不是根据每个 projectID 放置 ProjectType,而是为每个项目提供相同的 ProjectType
  • @Aarancibia - 那么我们需要更多信息。 Edit 提问并显示WS.ProjectData [] pr 中包含的数据。
  • 我已经编辑了这个问题,最后还有更多细节。再次感谢
猜你喜欢
  • 2017-01-20
  • 1970-01-01
  • 2020-04-29
  • 2011-08-20
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 2012-05-22
  • 2015-09-30
相关资源
最近更新 更多