这是我正在使用的JSON字符串。
#include <type_traits>
enum class EventType {
READ,
WRITE,
SIGNAL
};
class ReadEventHandle { };
class WriteEventHandle { };
class SignalEventHandle { };
ReadEventHandle re;
WriteEventHandle we;
SignalEventHandle se;
class EventHandle {
public:
template <EventType type, std::enable_if_t<type == EventType::READ>* = nullptr >
ReadEventHandle* cast () { return &re; }
template <EventType type, std::enable_if_t<type == EventType::WRITE>* = nullptr >
WriteEventHandle* cast () { return &we; }
template <EventType type, std::enable_if_t<type == EventType::SIGNAL>* = nullptr>
SignalEventHandle* cast () { return &se; }
};
void* check() {
return EventHandle().cast<EventType::READ>(); // Depending on cast argument, different pointers returned
}
我正在尝试获取SYMBOL,NAME,PRICE和&amp ;;的值列表。 AGG_VOLUME。到目前为止,这是我的代码:
string jsonText = "{
"?xml" : {
"@version" : "1.0",
"@encoding" : "UTF-8",
"@standalone" : "yes"
},
"Grid" : {
"DataRow" : [{
"DataItem" : [{
"@name" : "SYMBOL",
"#text" : "005930"
}, {
"@name" : "NAME",
"#text" : "Samsung Electronics"
}, {
"@name" : "PRICE",
"#text" : "1004.3"
}, {
"@name" : "VOLUME",
"#text" : "273.182"
}, {
"@name" : "AGG_VOLUME",
"#text" : "302.894"
}
]
}, {
"DataItem" : [{
"@name" : "SYMBOL",
"#text" : "AAPL"
}, {
"@name" : "NAME",
"#text" : "Apple Inc."
}, {
"@name" : "PRICE",
"#text" : "99"
}, {
"@name" : "VOLUME",
"#text" : "32936.4"
}, {
"@name" : "AGG_VOLUME",
"#text" : "33078.769"
}
]
}, {
"DataItem" : [{
"@name" : "SYMBOL",
"#text" : "MSFT"
}, {
"@name" : "NAME",
"#text" : "Microsoft Corporation"
}, {
"@name" : "PRICE",
"#text" : "42"
}, {
"@name" : "VOLUME",
"#text" : "103441.6"
}, {
"@name" : "AGG_VOLUME",
"#text" : "1324432.074"
}
]
}
]
}
}"
JObject feed = JObject.Parse(jsonText);
但我收到以下错误:
对象引用未设置为对象的实例。
我做错了什么?
答案 0 :(得分:2)
JToken.SelectTokens()
支持JSONPath query syntax。您可以使用此语法来执行所需的查询:
".."
是通配符递归下降运算符。因此,feed.SelectTokens("..DataItem")
查找名为DataItem
的所有JSON属性的值,无论它们在JSON层次结构中的位置。
"[?(@.@name == 'Value')]"
使用值为@name
的名为Value
的属性查询数组中的对象。
因此,以下是您所需要的:
var feed = JObject.Parse(jsonText);
var query = from item in feed.SelectTokens("..DataItem")
select new
{
SYMBOL = (string)item.SelectToken("[?(@.@name == 'SYMBOL')].#text"),
NAME = (string)item.SelectToken("[?(@.@name == 'NAME')].#text"),
PRICE = (string)item.SelectToken("[?(@.@name == 'PRICE')].#text"),
AGG_VOLUME = (string)item.SelectToken("[?(@.@name == 'AGG_VOLUME')].#text")
};
var list = query.ToList();
答案 1 :(得分:1)
您收到此错误是因为feed
引用了不直接包含JObject
属性的根DataItem
。因此feed["DataItem"]
返回null。然后,当您尝试取消引用此空表达式时,它会抛出NullReferenceException
。
您尝试获取的数据是JSON中的几个层,因此您的查询必须考虑到这一点。例如,要获取JSON中所有SYMBOL
值的列表,您需要执行以下操作:
List<string> symbols =
feed.SelectToken("Grid.DataRow")
.SelectMany(jt => jt["DataItem"])
.Where(jt => (string)jt["@name"] == "SYMBOL")
.Select(jt => (string)jt["#text"])
.ToList();