JSON.Net - 从多态 json 字符串中检索另一个数据
JSON.Net - Another data retrieval from a polymorphic json string
这是我的 JSON 字符串的样子:
{
"?xml" : {
"@version" : "1.0",
"@encoding" : "UTF-8"
},
"DataFeed" : {
"@FeedName" : "content",
"now" : "2016-10-17T14:11:38.00",
"Content" : [{
"ContentData" : {
"@statusType" : "Published",
"@isReleased" : "Yes",
"@docId" : "21756",
"ProductStatus" : {
"@productCategory" : "Issuer",
"@focus" : "Issuer",
"Symbol" : {
"@PrimarySymbol" : "GOOGL",
"@SecondarySymbol" : "Google",
"@BmId" : "1790"
}
},
"ContentVersion" : {
"@versionId" : "1",
"@lastVersion" : "true",
"@lastPublished" : "true",
"Url" : [{
"@type" : "XML",
"@size" : "146410",
"#cdata-section" : "https://aaa.yyy.com/docs/xml/708893eb-1fd9-4278-8b0e-e7e0738d8105.xml"
}, {
"@type" : "HTML",
"@size" : "46105",
"#cdata-section" : "https://aaa.yyy.com/docs/html/708893eb-1fd9-4278-8b0e-e7e0738d8105.html"
}, {
"@type" : "PDF",
"@size" : "1274885",
"#cdata-section" : "https://aaa.yyy.com/docs/pdf/708893eb-1fd9-4278-8b0e-e7e0738d8105.pdf"
}, {
"@type" : "ALTERNATE PDF",
"@size" : "60960",
"#cdata-section" : "https://aaa.yyy.com/docs/shortPdf/708893eb-1fd9-4278-8b0e-e7e0738d8105.pdf"
}
]
}
}
}, {
"ContentData" : {
"@statusType" : "Published",
"@isReleased" : "Yes",
"@docId" : "22457",
"ProductStatus" : {
"@productCategory" : "Issuer",
"@focus" : "Issuer",
"Symbol" : {
"@PrimarySymbol" : "AAPL",
"@SecondarySymbol" : "Apple",
"@BmId" : "1121"
}
},
"ContentVersion" : [{
"@versionId" : "1",
"@lastVersion" : "false",
"@lastPublished" : "false",
"Url" : [{
"@type" : "XML",
"#cdata-section" : "https://aaa.yyy.com/docs/version/708893eb-1fd9-4278-8b0e-e7e0738d8105.1476742297.xml"
}, {
"@type" : "HTML",
"#cdata-section" : "https://aaa.yyy.com/docs/version/708893eb-1fd9-4278-8b0e-e7e0738d8105.1476742297.html"
}, {
"@type" : "PDF",
"#cdata-section" : "https://aaa.yyy.com/docs/version/708893eb-1fd9-4278-8b0e-e7e0738d8105.1476742297.pdf"
}, {
"@type" : "ALTERNATE PDF",
"#cdata-section" : "https://aaa.yyy.com/docs/version/708893eb-1fd9-4278-8b0e-e7e0738d8105.1476742297_short.pdf"
}
]
}, {
"@versionId" : "2",
"@lastVersion" : "true",
"@lastPublished" : "true",
"Url" : [{
"@type" : "XML",
"@size" : "174520",
"#cdata-section" : "https://aaa.yyy.com/docs/xml/708893eb-1fd9-4278-8b0e-e7e0738d8105.xml"
}, {
"@type" : "HTML",
"@size" : "46105",
"#cdata-section" : "https://aaa.yyy.com/docs/html/708893eb-1fd9-4278-8b0e-e7e0738d8105.html"
}, {
"@type" : "PDF",
"@size" : "1270150",
"#cdata-section" : "https://aaa.yyy.com/docs/pdf/708893eb-1fd9-4278-8b0e-e7e0738d8105.pdf"
}, {
"@type" : "ALTERNATE PDF",
"@size" : "60960",
"#cdata-section" : "https://aaa.yyy.com/docs/version/708893eb-1fd9-4278-8b0e-e7e0738d8105.1577742297_short.pdf"
}
]
}
]
}
}, {
"ContentData" : {
"@statusType" : "Published",
"@isReleased" : "Yes",
"@docId" : "22501",
"ProductStatus" : {
"@productCategory" : "Issuer",
"@focus" : "Issuer",
"Symbol" : [{
"@PrimarySymbol" : "AAA",
"@SecondarySymbol" : "Some name 1",
"@BmId" : "561"
}, {
"@PrimarySymbol" : "ABC",
"@SecondarySymbol" : "Some Name 2",
"@BmId" : "29"
}, {
"@PrimarySymbol" : "BBB",
"@SecondarySymbol" : "Some Name 3",
"@BmId" : "36"
}, {
"@PrimarySymbol" : "CCC",
"@SecondarySymbol" : "Some Name 4",
"@BmId" : "624"
}
]
},
"ContentVersion" : {
"@versionId" : "1",
"@lastVersion" : "true",
"@lastPublished" : "true",
"Url" : [{
"@type" : "XML",
"@size" : "2706269",
"#cdata-section" : "https://aaa.yyy.com/docs/xml/1c420081-0ce5-4959-91d3-848bbbccd3e3.xml"
}, {
"@type" : "HTML",
"@size" : "32445",
"#cdata-section" : "https://aaa.yyy.com/docs/html/1c420081-0ce5-4959-91d3-848bbbccd3e3.html"
}, {
"@type" : "PDF",
"@size" : "887608",
"#cdata-section" : "https://aaa.yyy.com/docs/pdf/1c420081-0ce5-4959-91d3-848bbbccd3e3.pdf"
}, {
"@type" : "ALTERNATE PDF",
"@size" : "34366",
"#cdata-section" : "https://aaa.yyy.com/docs/shortPdf/1c420081-0ce5-4959-91d3-848bbbccd3e3.pdf"
}
]
}
}
}
]
}
}
我正在遵循 中的代码示例。我想要 select 以下内容,但前提是 Symbol
部分中只有一个发行人并且最新版本的 PDF url:
@docId
@PrimarySymbol
@BmId
#cdata-section
(但仅适用于最新版本的 PDF)
这是我的查询:
from content in jsonFeed.SelectTokens("DataFeed.Content").SelectMany(i => i.ObjectsOrSelf())
let issuer = content
.SelectToken("ContentData.ProductStatus.@productCategory")
.SingleOrMultiple()
.Select(t => (string)t)
.ToArray()
where issuer.FirstOrDefault().Equals("Issuer")
select new
{
DocID = (string)content.SelectToken("ContentData.@docId"),
Symbol = (string)content.SelectToken("ContentData.ProductStatus.Symbol.@PrimarySymbol"),
BMId = (int)content.SelectToken("ContentData.ProductStatus.Symbol.@BmId"),
PDFUrl = (string)content.SelectToken("ContentData.ContentVersion.Url[3].#cdata-section")
}).ToList();
现在,我可以成功获取 Google 的所有字段,但我无法获取 Apple 的 PDFUrl(因为我不知道如何获取最新版本)。另外,我怎样才能完成我的 Where 子句,以便它只 select 带有 1 个符号的文档?所以,最后,我的列表将是下图:
您可以组合 let
and where
来计算和筛选中间结果。
以下查询使用此技术,并且还查询 @type
等于 "PDF"
的 URL 而不是将其硬编码为索引 3(它实际上在索引 2 , 顺便说一下):
string pdfUrlType = "PDF";
var query =
(from content in jsonFeed.SelectTokens("DataFeed.Content").SelectMany(i => i.ObjectsOrSelf())
let issuer = content
.SelectToken("ContentData.ProductStatus.@productCategory")
.SingleOrMultiple()
.Select(t => (string)t)
.ToArray()
where issuer.FirstOrDefault().Equals("Issuer")
// Get the @PrimarySymbol where there is exactly one, or null otherwise.
let symbol = (string)content.SelectToken("ContentData.ProductStatus.Symbol.@PrimarySymbol")
// Skip content without a single primary symbol
where symbol != null
// Get the last ContentVersion record in the JSON document.
let lastContentVersion = content
.SelectToken("ContentData.ContentVersion")
.SingleOrMultiple()
.Where(v => (bool?)v.SelectToken("@lastVersion") == true)
.LastOrDefault()
// Skip content with no ContentVersion
where lastContentVersion != null
// Get the PDF Url record
let pdfUrl = lastContentVersion.SelectToken("Url")
.SingleOrMultiple()
.Where(u => (string)u.SelectToken("@type") == pdfUrlType)
.FirstOrDefault()
// Skip content with no PDF Url record
where pdfUrl != null
select new
{
DocID = (string)content.SelectToken("ContentData.@docId"),
Symbol = symbol,
BMId = (int?)content.SelectToken("ContentData.ProductStatus.Symbol.@BmId"),
PDFUrl = (string)pdfUrl.SelectToken("#cdata-section")
}).ToList();
如果您确实想要备用 PDF url,请设置
string pdfUrlType = "ALTERNATE PDF";
样本fiddle.
如果您确定每条 "Content"
记录中 ContentVersion
的最新版本("@lastVersion"
等于 "true"
的记录)保证是最后一个按文档顺序,可以简化查询如下:
let lastContentVersion = content
.SelectToken("ContentData.ContentVersion")
.SingleOrMultiple()
.LastOrDefault()
这是我的 JSON 字符串的样子:
{
"?xml" : {
"@version" : "1.0",
"@encoding" : "UTF-8"
},
"DataFeed" : {
"@FeedName" : "content",
"now" : "2016-10-17T14:11:38.00",
"Content" : [{
"ContentData" : {
"@statusType" : "Published",
"@isReleased" : "Yes",
"@docId" : "21756",
"ProductStatus" : {
"@productCategory" : "Issuer",
"@focus" : "Issuer",
"Symbol" : {
"@PrimarySymbol" : "GOOGL",
"@SecondarySymbol" : "Google",
"@BmId" : "1790"
}
},
"ContentVersion" : {
"@versionId" : "1",
"@lastVersion" : "true",
"@lastPublished" : "true",
"Url" : [{
"@type" : "XML",
"@size" : "146410",
"#cdata-section" : "https://aaa.yyy.com/docs/xml/708893eb-1fd9-4278-8b0e-e7e0738d8105.xml"
}, {
"@type" : "HTML",
"@size" : "46105",
"#cdata-section" : "https://aaa.yyy.com/docs/html/708893eb-1fd9-4278-8b0e-e7e0738d8105.html"
}, {
"@type" : "PDF",
"@size" : "1274885",
"#cdata-section" : "https://aaa.yyy.com/docs/pdf/708893eb-1fd9-4278-8b0e-e7e0738d8105.pdf"
}, {
"@type" : "ALTERNATE PDF",
"@size" : "60960",
"#cdata-section" : "https://aaa.yyy.com/docs/shortPdf/708893eb-1fd9-4278-8b0e-e7e0738d8105.pdf"
}
]
}
}
}, {
"ContentData" : {
"@statusType" : "Published",
"@isReleased" : "Yes",
"@docId" : "22457",
"ProductStatus" : {
"@productCategory" : "Issuer",
"@focus" : "Issuer",
"Symbol" : {
"@PrimarySymbol" : "AAPL",
"@SecondarySymbol" : "Apple",
"@BmId" : "1121"
}
},
"ContentVersion" : [{
"@versionId" : "1",
"@lastVersion" : "false",
"@lastPublished" : "false",
"Url" : [{
"@type" : "XML",
"#cdata-section" : "https://aaa.yyy.com/docs/version/708893eb-1fd9-4278-8b0e-e7e0738d8105.1476742297.xml"
}, {
"@type" : "HTML",
"#cdata-section" : "https://aaa.yyy.com/docs/version/708893eb-1fd9-4278-8b0e-e7e0738d8105.1476742297.html"
}, {
"@type" : "PDF",
"#cdata-section" : "https://aaa.yyy.com/docs/version/708893eb-1fd9-4278-8b0e-e7e0738d8105.1476742297.pdf"
}, {
"@type" : "ALTERNATE PDF",
"#cdata-section" : "https://aaa.yyy.com/docs/version/708893eb-1fd9-4278-8b0e-e7e0738d8105.1476742297_short.pdf"
}
]
}, {
"@versionId" : "2",
"@lastVersion" : "true",
"@lastPublished" : "true",
"Url" : [{
"@type" : "XML",
"@size" : "174520",
"#cdata-section" : "https://aaa.yyy.com/docs/xml/708893eb-1fd9-4278-8b0e-e7e0738d8105.xml"
}, {
"@type" : "HTML",
"@size" : "46105",
"#cdata-section" : "https://aaa.yyy.com/docs/html/708893eb-1fd9-4278-8b0e-e7e0738d8105.html"
}, {
"@type" : "PDF",
"@size" : "1270150",
"#cdata-section" : "https://aaa.yyy.com/docs/pdf/708893eb-1fd9-4278-8b0e-e7e0738d8105.pdf"
}, {
"@type" : "ALTERNATE PDF",
"@size" : "60960",
"#cdata-section" : "https://aaa.yyy.com/docs/version/708893eb-1fd9-4278-8b0e-e7e0738d8105.1577742297_short.pdf"
}
]
}
]
}
}, {
"ContentData" : {
"@statusType" : "Published",
"@isReleased" : "Yes",
"@docId" : "22501",
"ProductStatus" : {
"@productCategory" : "Issuer",
"@focus" : "Issuer",
"Symbol" : [{
"@PrimarySymbol" : "AAA",
"@SecondarySymbol" : "Some name 1",
"@BmId" : "561"
}, {
"@PrimarySymbol" : "ABC",
"@SecondarySymbol" : "Some Name 2",
"@BmId" : "29"
}, {
"@PrimarySymbol" : "BBB",
"@SecondarySymbol" : "Some Name 3",
"@BmId" : "36"
}, {
"@PrimarySymbol" : "CCC",
"@SecondarySymbol" : "Some Name 4",
"@BmId" : "624"
}
]
},
"ContentVersion" : {
"@versionId" : "1",
"@lastVersion" : "true",
"@lastPublished" : "true",
"Url" : [{
"@type" : "XML",
"@size" : "2706269",
"#cdata-section" : "https://aaa.yyy.com/docs/xml/1c420081-0ce5-4959-91d3-848bbbccd3e3.xml"
}, {
"@type" : "HTML",
"@size" : "32445",
"#cdata-section" : "https://aaa.yyy.com/docs/html/1c420081-0ce5-4959-91d3-848bbbccd3e3.html"
}, {
"@type" : "PDF",
"@size" : "887608",
"#cdata-section" : "https://aaa.yyy.com/docs/pdf/1c420081-0ce5-4959-91d3-848bbbccd3e3.pdf"
}, {
"@type" : "ALTERNATE PDF",
"@size" : "34366",
"#cdata-section" : "https://aaa.yyy.com/docs/shortPdf/1c420081-0ce5-4959-91d3-848bbbccd3e3.pdf"
}
]
}
}
}
]
}
}
我正在遵循 Symbol
部分中只有一个发行人并且最新版本的 PDF url:
@docId
@PrimarySymbol
@BmId
#cdata-section
(但仅适用于最新版本的 PDF)
这是我的查询:
from content in jsonFeed.SelectTokens("DataFeed.Content").SelectMany(i => i.ObjectsOrSelf())
let issuer = content
.SelectToken("ContentData.ProductStatus.@productCategory")
.SingleOrMultiple()
.Select(t => (string)t)
.ToArray()
where issuer.FirstOrDefault().Equals("Issuer")
select new
{
DocID = (string)content.SelectToken("ContentData.@docId"),
Symbol = (string)content.SelectToken("ContentData.ProductStatus.Symbol.@PrimarySymbol"),
BMId = (int)content.SelectToken("ContentData.ProductStatus.Symbol.@BmId"),
PDFUrl = (string)content.SelectToken("ContentData.ContentVersion.Url[3].#cdata-section")
}).ToList();
现在,我可以成功获取 Google 的所有字段,但我无法获取 Apple 的 PDFUrl(因为我不知道如何获取最新版本)。另外,我怎样才能完成我的 Where 子句,以便它只 select 带有 1 个符号的文档?所以,最后,我的列表将是下图:
您可以组合 let
and where
来计算和筛选中间结果。
以下查询使用此技术,并且还查询 @type
等于 "PDF"
的 URL 而不是将其硬编码为索引 3(它实际上在索引 2 , 顺便说一下):
string pdfUrlType = "PDF";
var query =
(from content in jsonFeed.SelectTokens("DataFeed.Content").SelectMany(i => i.ObjectsOrSelf())
let issuer = content
.SelectToken("ContentData.ProductStatus.@productCategory")
.SingleOrMultiple()
.Select(t => (string)t)
.ToArray()
where issuer.FirstOrDefault().Equals("Issuer")
// Get the @PrimarySymbol where there is exactly one, or null otherwise.
let symbol = (string)content.SelectToken("ContentData.ProductStatus.Symbol.@PrimarySymbol")
// Skip content without a single primary symbol
where symbol != null
// Get the last ContentVersion record in the JSON document.
let lastContentVersion = content
.SelectToken("ContentData.ContentVersion")
.SingleOrMultiple()
.Where(v => (bool?)v.SelectToken("@lastVersion") == true)
.LastOrDefault()
// Skip content with no ContentVersion
where lastContentVersion != null
// Get the PDF Url record
let pdfUrl = lastContentVersion.SelectToken("Url")
.SingleOrMultiple()
.Where(u => (string)u.SelectToken("@type") == pdfUrlType)
.FirstOrDefault()
// Skip content with no PDF Url record
where pdfUrl != null
select new
{
DocID = (string)content.SelectToken("ContentData.@docId"),
Symbol = symbol,
BMId = (int?)content.SelectToken("ContentData.ProductStatus.Symbol.@BmId"),
PDFUrl = (string)pdfUrl.SelectToken("#cdata-section")
}).ToList();
如果您确实想要备用 PDF url,请设置
string pdfUrlType = "ALTERNATE PDF";
样本fiddle.
如果您确定每条 "Content"
记录中 ContentVersion
的最新版本("@lastVersion"
等于 "true"
的记录)保证是最后一个按文档顺序,可以简化查询如下:
let lastContentVersion = content
.SelectToken("ContentData.ContentVersion")
.SingleOrMultiple()
.LastOrDefault()