【问题标题】:Geting XML in specific format c#以特定格式获取 XML c#
【发布时间】:2017-03-16 18:25:30
【问题描述】:

我正在开发 MVC Web API,其中一个函数我需要将 SQL DB 结果转换为 XML 文件。

private string DbToXml(int fileID)
        {
            DataSet ds = new DataSet("Requirements");
            string connetionString = ConfigurationManager.ConnectionStrings["DemoConnectionString"].ConnectionString;
            string XML;
            using (SqlConnection connection = new SqlConnection(connetionString))
            {
                string sql = "SELECT RequirementLabel as ID, VagueWord, Suggestion, Explanation, VaguePhrase, ContentText, VagueTypeText FROM [Test].[dbo].[Vague_Terms_View] where FileID=" + fileID;
                string XML_Output_Path = System.Configuration.ConfigurationManager.AppSettings.Get("XML_Output_Path");
                connection.Open();
                SqlDataAdapter adapter = new SqlDataAdapter(sql, connection);
                adapter.Fill(ds, "Requirement");
                var sb = new StringBuilder();
                XmlWriter xmlWrite = XmlWriter.Create(sb);
                ds.WriteXml(xmlWrite);
                XML = ds.GetXml();
            }

我从下面的代码中获取 XML,这是正确的。

<?xml version="1.0" encoding="utf-8"?>
<Requirements>
  <Requirement>
    <ID>Req97</ID>
    <VagueWord>or</VagueWord>
    <Suggestion>Keep each requirement in a single sentence.</Suggestion>
    <Explanation>Suggests that you are combining requirements. Requirements that contain conjunctions/disjunctions (AND/OR) are dangerous and can lead to downstream problems in defining scope of the requirement.</Explanation>
    <VaguePhrase>Marketing or Servicing</VaguePhrase>
    <ContentText>If a user is identified as Marketing or Servicing, then the Campaign Management (CM) hyperlink should be displayed.</ContentText>
    <VagueTypeText>Not Standard</VagueTypeText>
  </Requirement>
  <Requirement>
    <ID>Req97</ID>
    <VagueWord>should</VagueWord>
    <Suggestion>Use 'shall/must/will' for requirements,</Suggestion>
    <Explanation>Is often ambiguous, or inappropriate. Some readers will interpret these as optional or advisory, others as required.</Explanation>
    <ContentText>If a user is identified as Marketing or Servicing, then the Campaign Management (CM) hyperlink should be displayed.</ContentText>
    <VagueTypeText>Not Standard</VagueTypeText>
  </Requirement>
  <Requirement>
    <ID>Req98</ID>
    <VagueWord>Unless</VagueWord>
    <Suggestion>Specify each conditions explicitly. One condition per requirement.</Suggestion>
    <Explanation>Is an escape clause. Requirements with escape clauses are not testable. The word implies additional condition to the requirement.</Explanation>
    <ContentText>Unless Sleep, Latency, Noise, or apply conditions are present, the data transmissions will contain the code for Normal Operation.</ContentText>
    <VagueTypeText>Not Standard</VagueTypeText>
  </Requirement>
</Requirements>

但是现在我需要转换 XML,比如检查 Requirement 节点中的 ID 元素。如果它在下面的 Requirement 节点中重复,则重命名它和 Requirement 节点内的所有其他元素以附加 id=1 和编号等等。 上述 XML 的预期输出如下所示。

<?xml version="1.0" encoding="utf-8"?>
<Requirements>
  <Requirement>
    <ID "id=1">Req97</ID>
    <VagueWord "id=1">or</VagueWord>
    <Suggestion "id=1">Keep each requirement in a single sentence.</Suggestion>
    <Explanation "id=1">Suggests that you are combining requirements. Requirements that contain conjunctions/disjunctions (AND/OR) are dangerous and can lead to downstream problems in defining scope of the requirement.</Explanation>
    <VaguePhrase "id=1">Marketing or Servicing</VaguePhrase>
    <ContentText "id=1">If a user is identified as Marketing or Servicing, then the Campaign Management (CM) hyperlink should be displayed.</ContentText>
    <VagueTypeText "id=1">Not Standard</VagueTypeText>
  </Requirement>
  <Requirement>
    <ID "id=2">Req97</ID>
    <VagueWord "id=2">should</VagueWord>
    <Suggestion "id=2">Use 'shall/must/will' for requirements,</Suggestion>
    <Explanation "id=2">Is often ambiguous, or inappropriate. Some readers will interpret these as optional or advisory, others as required.</Explanation>
    <ContentText "id=2">If a user is identified as Marketing or Servicing, then the Campaign Management (CM) hyperlink should be displayed.</ContentText>
    <VagueTypeText "id=2">Not Standard</VagueTypeText>
  </Requirement>
  <Requirement>
    <ID>Req98</ID>
    <VagueWord>Unless</VagueWord>
    <Suggestion>Specify each conditions explicitly. One condition per requirement.</Suggestion>
    <Explanation>Is an escape clause. Requirements with escape clauses are not testable. The word implies additional condition to the requirement.</Explanation>
    <ContentText>Unless Sleep, Latency, Noise, or apply conditions are present, the data transmissions will contain the code for Normal Operation.</ContentText>
    <VagueTypeText>Not Standard</VagueTypeText>
  </Requirement>
</Requirements>

【问题讨论】:

  • @C Sharper,我认为需要实现自己的序列化。我过去尝试过,这并不容易,你会遇到性能问题。我会试着找到我的代码分享给你。
  • 您的id 属性值需要用引号括起来才能使该xml 有效。为什么最后一个节点没有idattribute?如果不想完成您的示例,请将其保留以使其保持一致。
  • @fabiosilvalima 如果你有请分享代码...这将是很大的帮助..!!!
  • 您是否考虑过使用FOR XML查询您的数据?
  • 你确定&lt;ID "id=1"&gt;Req97&lt;/ID&gt;?你的意思是&lt;ID id="1"&gt;Req97&lt;/ID&gt; 吗?因为您的示例不是有效的 XML。

标签: c# asp.net .net xml asp.net-web-api


【解决方案1】:

我使用了下面的解决方案,不确定它是否优化

 XmlElement root = returnXmlFile.DocumentElement;
         XmlNodeList nodes = root.ChildNodes;
         for (int i = 0; i < nodes.Count; i++)
         {
             string OuterIDvalue = nodes[i].ChildNodes[0].InnerText.ToString();
             const int idVal = 1;
             int counter = 1;
             if (nodes[i].FirstChild.Attributes.Count == 0)
             {
                 for (int ctrInner = 0; ctrInner < nodes[i].ChildNodes.Count; ctrInner++)
                 {
                     XmlAttribute xKey = returnXmlFile.CreateAttribute("id");
                     xKey.Value = idVal.ToString();
                     nodes[i].ChildNodes[ctrInner].Attributes.Append(xKey);
                 }
             }      
                 for (int j = i + 1; j < nodes.Count; j++)
                 {
                     string innerIDvalue = nodes[j].ChildNodes[0].InnerText.ToString();
                     if (OuterIDvalue == innerIDvalue && nodes[j].FirstChild.Attributes.Count == 0)
                     {
                         counter++;
                         for (int ctr = 0; ctr < nodes[j].ChildNodes.Count; ctr++)
                         {
                             XmlAttribute xKey = returnXmlFile.CreateAttribute("id");
                             xKey.Value = counter.ToString();
                             nodes[j].ChildNodes[ctr].Attributes.Append(xKey);
                         }
                     }
                 }
         }
         string xmlnew = returnXmlFile.InnerXml;
         returnXmlFile.Save(FileName);
        return xmlnew;
    }

【讨论】:

    【解决方案2】:
    var doc = XElement.Load("test.xml");
    
    var dict = doc.Elements("Requirement")
        .Elements("ID")
        .GroupBy(id => id.Value)
        .ToDictionary(id => id.Key, id => id.Count() > 1 ? 1 : 0);
    
    foreach (var req in doc.Elements("Requirement"))
    {
        var id = req.Element("ID").Value;
    
        if (dict[id] > 0)
        {
            foreach (var elem in req.Elements())
            {
                elem.Add(new XAttribute("id", dict[id]));
            }
            dict[id]++;
        }
    }
    

    现在doc 包含xml,并在需要的地方添加了id 属性。

    【讨论】:

    • 除非他确实需要来自上面的错误 XML("id=1" 而不是 id="1"),否则应该这样做。
    【解决方案3】:

    您可以对其进行反序列化(从 XML 创建对象),将您的 ID 修改为对象,然后将对象序列化回 XML,或者您可以直接编辑 XML。

    这是一个如何直接编辑 XML 的好例子:How to modify existing XML file with XmlDocument and XmlNode in C#

    【讨论】:

      猜你喜欢
      • 2021-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-13
      • 2021-02-12
      • 1970-01-01
      相关资源
      最近更新 更多