-Fixed incorrectly parsing scan filter when name is quoted
-Added support for multiple names in scan filter
This commit is contained in:
@@ -51,6 +51,81 @@ namespace Newtonsoft.Json.Tests.Linq.JsonPath
|
||||
[TestFixture]
|
||||
public class JPathExecuteTests : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void ScanQuoted()
|
||||
{
|
||||
string json = @"{
|
||||
""Node1"": {
|
||||
""Child1"": {
|
||||
""Name"": ""IsMe"",
|
||||
""TargetNode"": {
|
||||
""Prop1"": ""Val1"",
|
||||
""Prop2"": ""Val2""
|
||||
}
|
||||
},
|
||||
""My.Child.Node"": {
|
||||
""TargetNode"": {
|
||||
""Prop1"": ""Val1"",
|
||||
""Prop2"": ""Val2""
|
||||
}
|
||||
}
|
||||
},
|
||||
""Node2"": {
|
||||
""TargetNode"": {
|
||||
""Prop1"": ""Val1"",
|
||||
""Prop2"": ""Val2""
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
JObject models = JObject.Parse(json);
|
||||
|
||||
int result = models.SelectTokens("$..['My.Child.Node']").Count();
|
||||
Assert.AreEqual(1, result);
|
||||
|
||||
result = models.SelectTokens("..['My.Child.Node']").Count();
|
||||
Assert.AreEqual(1, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ScanMultipleQuoted()
|
||||
{
|
||||
string json = @"{
|
||||
""Node1"": {
|
||||
""Child1"": {
|
||||
""Name"": ""IsMe"",
|
||||
""TargetNode"": {
|
||||
""Prop1"": ""Val1"",
|
||||
""Prop2"": ""Val2""
|
||||
}
|
||||
},
|
||||
""My.Child.Node"": {
|
||||
""TargetNode"": {
|
||||
""Prop1"": ""Val3"",
|
||||
""Prop2"": ""Val4""
|
||||
}
|
||||
}
|
||||
},
|
||||
""Node2"": {
|
||||
""TargetNode"": {
|
||||
""Prop1"": ""Val5"",
|
||||
""Prop2"": ""Val6""
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
JObject models = JObject.Parse(json);
|
||||
|
||||
var results = models.SelectTokens("$..['My.Child.Node','Prop1','Prop2']").ToList();
|
||||
Assert.AreEqual("Val1", (string)results[0]);
|
||||
Assert.AreEqual("Val2", (string)results[1]);
|
||||
Assert.AreEqual(JTokenType.Object, results[2].Type);
|
||||
Assert.AreEqual("Val3", (string)results[3]);
|
||||
Assert.AreEqual("Val4", (string)results[4]);
|
||||
Assert.AreEqual("Val5", (string)results[5]);
|
||||
Assert.AreEqual("Val6", (string)results[6]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParseWithEmptyArrayContent()
|
||||
{
|
||||
|
||||
@@ -111,12 +111,11 @@ namespace Newtonsoft.Json.Linq.JsonPath
|
||||
member = null;
|
||||
}
|
||||
|
||||
PathFilter filter = (scan) ? (PathFilter)new ScanFilter { Name = member } : new FieldFilter { Name = member };
|
||||
filters.Add(filter);
|
||||
filters.Add(CreatePathFilter(member, scan));
|
||||
scan = false;
|
||||
}
|
||||
|
||||
filters.Add(ParseIndexer(currentChar));
|
||||
filters.Add(ParseIndexer(currentChar, scan));
|
||||
_currentIndex++;
|
||||
currentPartStartIndex = _currentIndex;
|
||||
followingIndexer = true;
|
||||
@@ -141,8 +140,7 @@ namespace Newtonsoft.Json.Linq.JsonPath
|
||||
member = null;
|
||||
}
|
||||
|
||||
PathFilter filter = (scan) ? (PathFilter)new ScanFilter { Name = member } : new FieldFilter { Name = member };
|
||||
filters.Add(filter);
|
||||
filters.Add(CreatePathFilter(member, scan));
|
||||
scan = false;
|
||||
}
|
||||
if (_currentIndex + 1 < _expression.Length && _expression[_currentIndex + 1] == '.')
|
||||
@@ -182,8 +180,7 @@ namespace Newtonsoft.Json.Linq.JsonPath
|
||||
{
|
||||
member = null;
|
||||
}
|
||||
PathFilter filter = (scan) ? (PathFilter)new ScanFilter { Name = member } : new FieldFilter { Name = member };
|
||||
filters.Add(filter);
|
||||
filters.Add(CreatePathFilter(member, scan));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -197,7 +194,13 @@ namespace Newtonsoft.Json.Linq.JsonPath
|
||||
return atPathEnd;
|
||||
}
|
||||
|
||||
private PathFilter ParseIndexer(char indexerOpenChar)
|
||||
private static PathFilter CreatePathFilter(string member, bool scan)
|
||||
{
|
||||
PathFilter filter = (scan) ? (PathFilter)new ScanFilter {Name = member} : new FieldFilter {Name = member};
|
||||
return filter;
|
||||
}
|
||||
|
||||
private PathFilter ParseIndexer(char indexerOpenChar, bool scan)
|
||||
{
|
||||
_currentIndex++;
|
||||
|
||||
@@ -209,7 +212,7 @@ namespace Newtonsoft.Json.Linq.JsonPath
|
||||
|
||||
if (_expression[_currentIndex] == '\'')
|
||||
{
|
||||
return ParseQuotedField(indexerCloseChar);
|
||||
return ParseQuotedField(indexerCloseChar, scan);
|
||||
}
|
||||
else if (_expression[_currentIndex] == '?')
|
||||
{
|
||||
@@ -710,7 +713,7 @@ namespace Newtonsoft.Json.Linq.JsonPath
|
||||
throw new JsonException("Could not read query operator.");
|
||||
}
|
||||
|
||||
private PathFilter ParseQuotedField(char indexerCloseChar)
|
||||
private PathFilter ParseQuotedField(char indexerCloseChar, bool scan)
|
||||
{
|
||||
List<string> fields = null;
|
||||
|
||||
@@ -726,11 +729,13 @@ namespace Newtonsoft.Json.Linq.JsonPath
|
||||
if (fields != null)
|
||||
{
|
||||
fields.Add(field);
|
||||
return new FieldMultipleFilter { Names = fields };
|
||||
return (scan)
|
||||
? (PathFilter)new ScanMultipleFilter { Names = fields }
|
||||
: (PathFilter)new FieldMultipleFilter { Names = fields };
|
||||
}
|
||||
else
|
||||
{
|
||||
return new FieldFilter { Name = field };
|
||||
return CreatePathFilter(field, scan);
|
||||
}
|
||||
}
|
||||
else if (_expression[_currentIndex] == ',')
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Newtonsoft.Json.Linq.JsonPath
|
||||
{
|
||||
internal class ScanMultipleFilter : PathFilter
|
||||
{
|
||||
public List<string> Names { get; set; }
|
||||
|
||||
public override IEnumerable<JToken> ExecuteFilter(JToken root, IEnumerable<JToken> current, bool errorWhenNoMatch)
|
||||
{
|
||||
foreach (JToken c in current)
|
||||
{
|
||||
JToken value = c;
|
||||
JToken container = c;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (container != null && container.HasValues)
|
||||
{
|
||||
value = container.First;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (value != null && value != c && value == value.Parent.Last)
|
||||
{
|
||||
value = value.Parent;
|
||||
}
|
||||
|
||||
if (value == null || value == c)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
value = value.Next;
|
||||
}
|
||||
|
||||
JProperty e = value as JProperty;
|
||||
if (e != null)
|
||||
{
|
||||
foreach (string name in Names)
|
||||
{
|
||||
if (e.Name == name)
|
||||
{
|
||||
yield return e.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
container = value as JContainer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,6 +125,7 @@
|
||||
<Compile Include="Linq\JsonPath\QueryFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\RootFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\ScanFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\ScanMultipleFilter.cs" />
|
||||
<Compile Include="Linq\MergeArrayHandling.cs" />
|
||||
<Compile Include="Linq\MergeNullValueHandling.cs" />
|
||||
<Compile Include="MetadataPropertyHandling.cs" />
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
<Compile Include="Linq\JsonPath\QueryFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\RootFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\ScanFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\ScanMultipleFilter.cs" />
|
||||
<Compile Include="Linq\MergeArrayHandling.cs" />
|
||||
<Compile Include="Linq\MergeNullValueHandling.cs" />
|
||||
<Compile Include="MetadataPropertyHandling.cs" />
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
<Compile Include="Linq\JsonPath\QueryFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\RootFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\ScanFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\ScanMultipleFilter.cs" />
|
||||
<Compile Include="Linq\MergeArrayHandling.cs" />
|
||||
<Compile Include="Linq\MergeNullValueHandling.cs" />
|
||||
<Compile Include="MetadataPropertyHandling.cs" />
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
<Compile Include="Linq\JsonPath\QueryFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\RootFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\ScanFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\ScanMultipleFilter.cs" />
|
||||
<Compile Include="Linq\JToken.cs" />
|
||||
<Compile Include="Linq\JTokenEqualityComparer.cs" />
|
||||
<Compile Include="Linq\JTokenReader.cs" />
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
<Compile Include="Linq\JsonPath\QueryFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\RootFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\ScanFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\ScanMultipleFilter.cs" />
|
||||
<Compile Include="Linq\JToken.cs" />
|
||||
<Compile Include="Linq\JTokenEqualityComparer.cs" />
|
||||
<Compile Include="Linq\JTokenReader.cs" />
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
<Compile Include="Linq\JsonPath\QueryExpression.cs" />
|
||||
<Compile Include="Linq\JsonPath\QueryFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\RootFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\ScanMultipleFilter.cs" />
|
||||
<Compile Include="Linq\JsonPath\ScanFilter.cs" />
|
||||
<Compile Include="Linq\JToken.cs" />
|
||||
<Compile Include="Linq\JTokenEqualityComparer.cs" />
|
||||
|
||||
Reference in New Issue
Block a user