2015-05-14 68 views
4

在項目中,我使用TSQL FOR XML從數據庫獲取一些數據。在所有表格中,日期字段的最小值設置爲01/01/1900從XML轉換爲JSON時更改屬性值

這是因爲不允許空值作爲無法更改的內部策略。

隨着XML結果我需要將其轉換爲JSON和序列化到客戶端。

對於這樣我使用:

string jSonString = Newtonsoft.Json.JsonConvert.SerializeXmlNode(xmlDoc, Newtonsoft.Json.Formatting.None, true); 

好;現在我需要將每個01/01/1900日期轉換爲DateTime.MinValue(01/01/0001),同時轉換爲JSON;我該如何處理?

+0

這聽起來像數據庫中的一個糟糕的設計開始 - 那些日期列應該爲空來表示沒有日期而不是01/01/1900 - 我會開始糾正它。 –

+0

@TrevorPilley我知道,但空值不允許作爲不能改變的內部策略。添加到問題中。 –

回答

1

UPDATE - 修改後的代碼可用於任何節點/屬性,其值爲01/01/1900

我會在轉換爲JSON之前處理XML文檔。如果您的日期值是節點或屬性值,那麼如何做LinqPad示例如下。因爲我不知道你的XML數據結構與裸簡單的例子:

void Main() 
{ 
    // IF IT IS NODE VALUE 
    var xml = @"<data> 
     <objectA> 
      <dateValueA>01/01/1900</dateValueA> 
      <dateValueB>01/01/1971</dateValueB> 
     </objectA> 
     <objectB> 
      <dateValueA>01/01/2002</dateValueA> 
      <dateValueB>01/01/1900</dateValueB> 
      <dateValueZ>01/01/2011</dateValueZ> 
     </objectB> 
     <objectC> 
      <dateValueA>01/01/1910</dateValueA> 
      <dateValueB>01/01/2012</dateValueB> 
      <dateValueC>01/01/1900</dateValueC> 
     </objectC> 
    </data>"; 

    var xmlDoc = new XmlDocument(); 
    xmlDoc.LoadXml(xml); 

    var nodes = xmlDoc.SelectNodes("//*[text()='01/01/1900']"); 
    foreach(XmlNode node in nodes) 
    { 
     node.InnerText = "01/01/0001"; 
    } 

    string jSonString = Newtonsoft.Json.JsonConvert.SerializeXmlNode(xmlDoc, Newtonsoft.Json.Formatting.None, true); 

    "// IF IT IS NODE VALUE - RESULTS".Dump(); 
    jSonString.Dump(); 

    // IF IT IS ATTRIBUTE VALUE 
    var xmlAttr = @"<data> 
     <objectA dateValueA='01/01/1900' dateValueB='01/01/1900' dateValueC='01/01/2011' /> 
     <objectB dateValueB='01/01/2011' someOtherDate='01/01/1900' /> 
     <objectC dateValueC='01/01/1900' dontChangeThisDate='05/04/1923' /> 
    </data>"; 

    var xmlDocAttr = new XmlDocument(); 
    xmlDoc.LoadXml(xmlAttr); 

    var nodesAttr = xmlDoc.SelectNodes("//*[@*='01/01/1900']"); 
    for(var i=0; i < nodesAttr.Count; i++) 
    { 
     foreach(XmlAttribute attrib in nodesAttr[i].Attributes) 
     { 
      if (attrib.Value == "01/01/1900") 
      { 
       attrib.Value = "01/01/0001"; 
      } 
     } 
    } 

    string jSonStringAttr = Newtonsoft.Json.JsonConvert.SerializeXmlNode(xmlDoc, Newtonsoft.Json.Formatting.None, true); 

    "// IF IT IS ATTRIBUTE VALUE - RESULTS".Dump(); 
    jSonStringAttr.Dump(); 

} 

和結果:

// IF IT IS NODE VALUE - RESULTS 
{"objectA":{"dateValueA":"01/01/0001","dateValueB":"01/01/1971"},"objectB":{"dateValueA":"01/01/2002","dateValueB":"01/01/0001","dateValueZ":"01/01/2011"},"objectC":{"dateValueA":"01/01/1910","dateValueB":"01/01/2012","dateValueC":"01/01/0001"}} 

// IF IT IS ATTRIBUTE VALUE - RESULTS 
{"objectA":{"@dateValueA":"01/01/0001","@dateValueB":"01/01/0001","@dateValueC":"01/01/2011"},"objectB":{"@dateValueB":"01/01/2011","@someOtherDate":"01/01/0001"},"objectC":{"@dateValueC":"01/01/0001","@dontChangeThisDate":"05/04/1923"}} 

會爲你工作?

+0

我不能以這種方式處理問題;我的函數必須是通用的(用於某些SP),並且我無法以編程方式知道DateTime列的名稱 –

+0

@IvinvinDominin我更新了代碼以處理值爲「01/01/1900」的任何節點或屬性名稱。這會起作用嗎? – CrnaStena

+0

唯一的副作用是包含該值的字符串也將被轉換。我有點擔心,在中等長度的XML上運行正則表達式可能會花費不菲 –

0

如果你控制的T-SQL,你可以試着在查詢替換值:

CASE 
    WHEN [DateWhichCantBeNull] = '1900-01-01' 
     THEN '0001-01-01' 
    ELSE [DateWhichCantBeNull] 
END AS "DateWhichCantBeNull" 

您可能需要轉換,作爲DateTime2如果仍然需要爲序列化到真正的約會正常工作。

+0

這是我第一次想到的,但我使用的SP無法更改。我知道這個結構有一些限制... –