Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中读取json时以编程方式转义特殊字符?_C#_Json_Json.net_Jpath - Fatal编程技术网

如何在C#中读取json时以编程方式转义特殊字符?

如何在C#中读取json时以编程方式转义特殊字符?,c#,json,json.net,jpath,C#,Json,Json.net,Jpath,在json消息中,我有一个字段Name,它可以包含不同特殊字符的各种组合。由于特殊字符,当我筛选此属性时,会出现错误: 分析路径查询时出现意外字符: 此属性的值不是固定的。由于特殊字符的组合事先未知,因此在应用jpath筛选属性时,我无法应用特定的转义序列 例如:如果'Name':''!!!'然后,$…[?(@Name=='\'!!!')]将解决此问题。但是,同一字段也可以有类似于'Name':'A!!!'。在这种情况下,相同的转义序列将失败 [Test] public static

在json消息中,我有一个字段
Name
,它可以包含不同特殊字符的各种组合。由于特殊字符,当我筛选此属性时,会出现错误:

分析路径查询时出现意外字符:

此属性的值不是固定的。由于特殊字符的组合事先未知,因此在应用jpath筛选属性时,我无法应用特定的转义序列

例如:如果
'Name':''!!!'
然后,
$…[?(@Name=='\'!!!')]
将解决此问题。但是,同一字段也可以有类似于
'Name':'A!!!'。在这种情况下,相同的转义序列将失败

 [Test]
    public static void Test()
    {
        string json = @"{'Type': 'Contoso',
             'Products': [
                 {
                 'Name': ''!!!',
                 'Price': 99.95
                 }]
                    }";
        var jobject = JToken.Parse(json);
        string name = (string) jobject.SelectToken("$..[?(@Name== ''!!!')]");

    }
Name
的其他可能组合是
'Name':'!“!!”
“名称”:”!!”
“名称”:“$”!!“
“名称”:“/”!!”
'Name':'等。

是否有一种通用的方法以编程方式转义特殊字符,以便处理所有组合?

这应该自动转义未转义的撇号。如果JSON包含多个未转义的撇号,它应该递归,直到所有撇号都被修复

但是,实际上,您应该联系生成错误JSON的人,并要求他们纠正错误

private static JToken ParseWithAutoEscape(string json)
{
    try
    {
        return JToken.Parse(json);
    }
    catch (JsonReaderException ex)
    {
        if (!ex.Message.StartsWith("After parsing a value an unexpected character was encountered:"))
            throw;

        var lines = json.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
        var badLine = lines[ex.LineNumber - 1];

        // contains the part of the line before the apostrophe
        var before = badLine.Substring(0, ex.LinePosition - 1);

        // contains the apostrophe and what comes after.
        var after = badLine.Substring(ex.LinePosition - 1);

        lines[ex.LineNumber - 1] = $"{before}\\{after}";
        json = String.Join("\n", lines);

        // try again.
        return ParseWithAutoEscape(json);
    }
}
用法:

var jobject = ParseWithAutoEscape(json);
var name = jobject.SelectToken("$..[?(@Name== '\\'!!!')]");
Debug.WriteLine(name);
请注意,
也需要在查询选择器中转义。

正如Amy所说,json(字符串json)是问题所在,而不是jpath表达式。它包含无效的json,因为
'Name':''!!!'不是有效的json。您需要将单引号转义到
\'

它需要如下所示:

    string json = @"{'Type': 'Contoso',
         'Products': [
             {
             'Name': '\'!!!',
             'Price': 99.95
             }]
                }";
    string json = @"{'Type': 'Contoso',
         'Products': [
             {
             'Name': '\'!!!',
             'Price': 99.95
             }]
                }";
    var jobject = JObject.Parse(json);
    string name = (string)jobject.SelectToken("$.Products[?(@.Name =~ /.*!!$/i)].Name");
如果您对json转义序列有进一步的疑问,请尝试了解以下内容:

如果你说“转义特殊字符”时真正要说的是如何在JPath中使用通配符表达式(我之所以怀疑是因为你列出了一堆!!-结尾模式),那么你可以尝试以下方法:

    string json = @"{'Type': 'Contoso',
         'Products': [
             {
             'Name': '\'!!!',
             'Price': 99.95
             }]
                }";
    string json = @"{'Type': 'Contoso',
         'Products': [
             {
             'Name': '\'!!!',
             'Price': 99.95
             }]
                }";
    var jobject = JObject.Parse(json);
    string name = (string)jobject.SelectToken("$.Products[?(@.Name =~ /.*!!$/i)].Name");

它将匹配一个JavaScript正则表达式,任何以!!(两个感叹号)。

A有什么问题吗!!!'价值看起来像是正确的字符串“A!!!”没有问题。。我的意思是说属性“Name”也可以以非特殊字符开头,这不需要转义。所以你只会遇到Name-value的问题,对吗?请添加更多问题输入示例(如有)。或者,唯一可能的情况是当名称值看起来像
“某个字符串”
?@AleksAndreev我已经更新了其他示例输入。
“名称”:“!!”是无效的JSON。如果字符串要包含单个撇号,则需要对其进行转义。否则,需要删除重复的撇号。非常感谢@Amy提供详细的解决方案。。否则我就不会想到这种方法。。这个解决方案解决了我的部分问题。未解决的部分是,在解析之后,它需要使用转义字符保存值,这样我就可以将相同的值传递给jpath,而不必担心转义的需要……您不是在查询提前知道的名称吗?不总是这样!。。。在实际场景中,我将从端点获得完整响应,然后使用jsonpath筛选名称。。然后我将使用由此获得的值来执行更多的操作。。。我不知道名字之前的值……我不认为你应该查询一个特定的名称,而应该重复对产品的数组。如果你发现我的答案是有用的,请考虑接受它。谢谢