C# 从XML转换为JSON时更改属性值
在一个项目中,我使用TSQLForXML从数据库中获取一些数据。在所有表格中,日期字段的最小值设置为C# 从XML转换为JSON时更改属性值,c#,json.net,C#,Json.net,在一个项目中,我使用TSQLForXML从数据库中获取一些数据。在所有表格中,日期字段的最小值设置为01/01/1900 这是因为不允许将空值作为不能更改的内部策略 对于xml结果,我需要将其转换为JSON并将其序列化到客户端 为此,我使用: string jSonString = Newtonsoft.Json.JsonConvert.SerializeXmlNode(xmlDoc, Newtonsoft.Json.Formatting.None, true); 好,;现在我需要将每个01/
01/01/1900
这是因为不允许将空值作为不能更改的内部策略
对于xml结果,我需要将其转换为JSON并将其序列化到客户端
为此,我使用:
string jSonString = Newtonsoft.Json.JsonConvert.SerializeXmlNode(xmlDoc, Newtonsoft.Json.Formatting.None, true);
好,;现在我需要将每个
01/01/1900
date转换为DateTime.MinValue
(01/01/0001),同时转换为JSON;如何处理此问题?如果控制T-SQL,可以尝试替换查询中的值:
CASE
WHEN [DateWhichCantBeNull] = '1900-01-01'
THEN '0001-01-01'
ELSE [DateWhichCantBeNull]
END AS "DateWhichCantBeNull"
如果仍然需要将其转换为实际日期才能使序列化正常工作,则可能需要将其转换为
DateTime2
。更新-修改后的代码以适用于任何具有值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();
}
这对您有用吗?这听起来像是数据库中的一个糟糕的设计开始-这些日期列应该为null,以表示没有日期,而不是1900年1月1日-我会首先更正它。@TrevorPilley我知道,但是null值不允许作为一个不能更改的内部策略。这是我的第一个想法,但我使用的SP无法更改。我知道这种结构有一些限制…我不能用这种方式处理问题;我的函数必须是泛型的(用于某些SP),并且我无法通过编程知道DateTime的名称columns@IrvinDominin我更新了代码,以使用任何具有值
01/01/1900
的节点或属性名称。这样行吗?唯一的副作用是包含该值的字符串也将被转换。我有点担心在中等长度的xml上运行正则表达式可能会带来成本expensive@IrvinDominin这是不对的。上面的示例不会更改字符串内部的值,它与节点或属性的值完全匹配。我也不确定您是否担心“成本高昂”。您必须扫描整个文档以查找需要替换的值。我很想知道你最终会做什么,因为这是一个很好的问题,我想知道未来的使用方法。最后,我使用这个解决方案,在我的测试中成本不高。非常感谢。
// 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"}}