如何使用 RapidXML C++ 检查 xml 中的空标签
How check empty tag in xml with RapidXML c++
存在XML:
<?xml version="1.0" encoding="UTF-8"?>
<ServerData>
<NetJobChunk id="599">
<Frames>0.000 - 0.000</Frames>
<EndTime>0</EndTime>
<ChunkID>1</ChunkID>
<StartDateTime>42212.713495</StartDateTime>
<RenderedFiles></RenderedFiles>
<AttemptsText>0</AttemptsText>
<RenderingTimeText>n/a</RenderingTimeText>
<Slice>Entire image</Slice>
<Attempts>0</Attempts>
<ErrorCount>0</ErrorCount>
<StartDateText>27.07.2015 17:07:26</StartDateText>
<RenderingClient></RenderingClient>
<Priority>0</Priority>
<StartTime>0</StartTime>
<NetJobID>599</NetJobID>
<ExtSplitting>None</ExtSplitting>
<AvgCPUUsage>0.000000</AvgCPUUsage>
<RenderingClientUuid>00000000-0000-0000-0000-000000000000</RenderingClientUuid>
<History></History>
<CacheScenesLocally>false</CacheScenesLocally>
<RenderingTime>0</RenderingTime>
<RecacheScenes>false</RecacheScenes>
<StateMachineState>0</StateMachineState>
<Scene>P:\ftpuser\F20141088\Scene_news\3dsmax\test.max</Scene>
<StatusText>Done</StatusText>
<Status>4</Status>
</NetJobChunk>
<NetJobChunk id="599">
<Frames>1.000 - 1.000</Frames>
<EndTime>0</EndTime>
<ChunkID>2</ChunkID>
<StartDateTime>42212.713495</StartDateTime>
<RenderedFiles></RenderedFiles>
<AttemptsText>0</AttemptsText>
<RenderingTimeText>n/a</RenderingTimeText>
<Slice>Entire image</Slice>
<Attempts>0</Attempts>
<ErrorCount>0</ErrorCount>
<StartDateText>27.07.2015 17:07:26</StartDateText>
<RenderingClient></RenderingClient>
<Priority>0</Priority>
<StartTime>0</StartTime>
<NetJobID>599</NetJobID>
<ExtSplitting>None</ExtSplitting>
<AvgCPUUsage>0.000000</AvgCPUUsage>
<RenderingClientUuid>00000000-0000-0000-0000-000000000000</RenderingClientUuid>
<History></History>
<CacheScenesLocally>false</CacheScenesLocally>
<RenderingTime>0</RenderingTime>
<RecacheScenes>false</RecacheScenes>
<StateMachineState>0</StateMachineState>
<Scene>P:\ftpuser\F20141088\Scene_news\3dsmax\test.max</Scene>
<StatusText>Done</StatusText>
<Status>4</Status>
</NetJobChunk>
<NetJobChunk id="601">
<Frames>0.000 - 0.000</Frames>
<EndTime>0</EndTime>
<ChunkID>1</ChunkID>
<StartDateTime>42212.852882</StartDateTime>
<RenderedFiles></RenderedFiles>
<AttemptsText>1 (max)</AttemptsText>
<RenderingTimeText>n/a</RenderingTimeText>
<Slice>Entire image</Slice>
<Attempts>1</Attempts>
<ErrorCount>1</ErrorCount>
<StartDateText></StartDateText>
<RenderingClient></RenderingClient>
<Priority>0</Priority>
<StartTime>0</StartTime>
<NetJobID>601</NetJobID>
<ExtSplitting>Camera: 005</ExtSplitting>
<AvgCPUUsage>0.000000</AvgCPUUsage>
<RenderingClientUuid>00000000-0000-0000-0000-000000000000</RenderingClientUuid>
<History>
<Value>1|1437999253|Rendering started [RENDERHOST202]|</Value>
<Value>4|1438010887|27.07.2015 20:28:07; Error rendering frame 0: An unexpected exception has occurred in the network renderer and it is terminating.|</Value>
<Value>4|1438010888|Chunk error: The renderer returned an error-code (0x3) [RENDERHOST202]|</Value>
<Value>1|1438010889|Rendering started [RENDERHOST202]|</Value>
<Value>3|1438017456|Chunk cancelled [RENDERHOST202]|</Value>
<Value>3|1438017456|Net Job cancelled by user|</Value>
</History>
<CacheScenesLocally>false</CacheScenesLocally>
<RenderingTime>0</RenderingTime>
<RecacheScenes>false</RecacheScenes>
<StateMachineState>0</StateMachineState>
<Scene>P:\ftpuser\F20131020\2House_22_2015_07_27_12_16_55\2House_22.max</Scene>
<StatusText>Cancelled</StatusText>
<Status>5</Status>
</NetJobChunk>
</ServerData>
要求接收标签最后一个事件的最大值时间(单位为ticks)"History":
<History>
<Value>...</Value>
</History>.
标签 "History" 可以为空:
<History></History>.
解析:
...
char* ch = new char[xml.size()+1];
std::copy(xml.begin(), xml.end(), ch);
ch[xml.size()] = '[=14=]';
xml_document<char> doc;
doc.parse<0>(ch);
unsigned long LastEventTime = 0;
xml_node<> *root_node = doc.first_node("ServerData");
for (xml_node<> * chunk_node = root_node->first_node("NetJobChunk"); chunk_node; chunk_node = chunk_node->next_sibling())
{
// History
unsigned long result = ParseChunkLastEventTime(chunk_node);
if(result > LastEventTime)
LastEventTime = result;
}
...
unsigned long CRapidXmlParser::ParseChunkLastEventTime(xml_node<char>* chunk_node) {
unsigned long val = 0;
if(chunk_node == nullptr)
throw std::exception("ParseChunkLastEventTime: null ptr chunk_node");
xml_node<> * chunk_hist_node = chunk_node->first_node("History");
xml_node<> * last_value_node = chunk_hist_node->last_node("Value");// ERROR!!!
if(last_value_node) {
std::string last_event = last_value_node->value();
size_t time_begin = last_event.find_first_of('|');
if(time_begin != std::string::npos) {
size_t time_end = last_event.find_first_of('|', time_begin+1);
if(time_end != std::string::npos) {
val = boost::lexical_cast<unsigned long>(last_event.substr(time_begin+1, time_end-time_begin-1) );
}
}
}
return val;
}
当我尝试获取空标签的最后一个子标签 ("Value") 时 "History" - 我得到一个异常,而不是预期的空指针。有什么问题?
需要使用first_node(),检查节点是否有子节点。
unsigned long CRapidXmlParser::ParseChunkLastEventTime(xml_node<char>* chunk_node) {
unsigned long val = 0;
if(chunk_node == nullptr)
throw std::exception("ParseChunkLastEventTime: null ptr chunk_node");
xml_node<> * chunk_hist_node = chunk_node->first_node("History");
if(chunk_hist_node->first_node("Value")) {
xml_node<> * last_value_node = chunk_hist_node->last_node("Value");
if(last_value_node) {
std::string last_event = last_value_node->value();
size_t time_begin = last_event.find_first_of('|');
if(time_begin != std::string::npos) {
size_t time_end = last_event.find_first_of('|', time_begin+1);
if(time_end != std::string::npos) {
val = boost::lexical_cast<unsigned long>(last_event.substr(time_begin+1, time_end-time_begin-1) );
}
}
}
}
return val;
}
存在XML:
<?xml version="1.0" encoding="UTF-8"?>
<ServerData>
<NetJobChunk id="599">
<Frames>0.000 - 0.000</Frames>
<EndTime>0</EndTime>
<ChunkID>1</ChunkID>
<StartDateTime>42212.713495</StartDateTime>
<RenderedFiles></RenderedFiles>
<AttemptsText>0</AttemptsText>
<RenderingTimeText>n/a</RenderingTimeText>
<Slice>Entire image</Slice>
<Attempts>0</Attempts>
<ErrorCount>0</ErrorCount>
<StartDateText>27.07.2015 17:07:26</StartDateText>
<RenderingClient></RenderingClient>
<Priority>0</Priority>
<StartTime>0</StartTime>
<NetJobID>599</NetJobID>
<ExtSplitting>None</ExtSplitting>
<AvgCPUUsage>0.000000</AvgCPUUsage>
<RenderingClientUuid>00000000-0000-0000-0000-000000000000</RenderingClientUuid>
<History></History>
<CacheScenesLocally>false</CacheScenesLocally>
<RenderingTime>0</RenderingTime>
<RecacheScenes>false</RecacheScenes>
<StateMachineState>0</StateMachineState>
<Scene>P:\ftpuser\F20141088\Scene_news\3dsmax\test.max</Scene>
<StatusText>Done</StatusText>
<Status>4</Status>
</NetJobChunk>
<NetJobChunk id="599">
<Frames>1.000 - 1.000</Frames>
<EndTime>0</EndTime>
<ChunkID>2</ChunkID>
<StartDateTime>42212.713495</StartDateTime>
<RenderedFiles></RenderedFiles>
<AttemptsText>0</AttemptsText>
<RenderingTimeText>n/a</RenderingTimeText>
<Slice>Entire image</Slice>
<Attempts>0</Attempts>
<ErrorCount>0</ErrorCount>
<StartDateText>27.07.2015 17:07:26</StartDateText>
<RenderingClient></RenderingClient>
<Priority>0</Priority>
<StartTime>0</StartTime>
<NetJobID>599</NetJobID>
<ExtSplitting>None</ExtSplitting>
<AvgCPUUsage>0.000000</AvgCPUUsage>
<RenderingClientUuid>00000000-0000-0000-0000-000000000000</RenderingClientUuid>
<History></History>
<CacheScenesLocally>false</CacheScenesLocally>
<RenderingTime>0</RenderingTime>
<RecacheScenes>false</RecacheScenes>
<StateMachineState>0</StateMachineState>
<Scene>P:\ftpuser\F20141088\Scene_news\3dsmax\test.max</Scene>
<StatusText>Done</StatusText>
<Status>4</Status>
</NetJobChunk>
<NetJobChunk id="601">
<Frames>0.000 - 0.000</Frames>
<EndTime>0</EndTime>
<ChunkID>1</ChunkID>
<StartDateTime>42212.852882</StartDateTime>
<RenderedFiles></RenderedFiles>
<AttemptsText>1 (max)</AttemptsText>
<RenderingTimeText>n/a</RenderingTimeText>
<Slice>Entire image</Slice>
<Attempts>1</Attempts>
<ErrorCount>1</ErrorCount>
<StartDateText></StartDateText>
<RenderingClient></RenderingClient>
<Priority>0</Priority>
<StartTime>0</StartTime>
<NetJobID>601</NetJobID>
<ExtSplitting>Camera: 005</ExtSplitting>
<AvgCPUUsage>0.000000</AvgCPUUsage>
<RenderingClientUuid>00000000-0000-0000-0000-000000000000</RenderingClientUuid>
<History>
<Value>1|1437999253|Rendering started [RENDERHOST202]|</Value>
<Value>4|1438010887|27.07.2015 20:28:07; Error rendering frame 0: An unexpected exception has occurred in the network renderer and it is terminating.|</Value>
<Value>4|1438010888|Chunk error: The renderer returned an error-code (0x3) [RENDERHOST202]|</Value>
<Value>1|1438010889|Rendering started [RENDERHOST202]|</Value>
<Value>3|1438017456|Chunk cancelled [RENDERHOST202]|</Value>
<Value>3|1438017456|Net Job cancelled by user|</Value>
</History>
<CacheScenesLocally>false</CacheScenesLocally>
<RenderingTime>0</RenderingTime>
<RecacheScenes>false</RecacheScenes>
<StateMachineState>0</StateMachineState>
<Scene>P:\ftpuser\F20131020\2House_22_2015_07_27_12_16_55\2House_22.max</Scene>
<StatusText>Cancelled</StatusText>
<Status>5</Status>
</NetJobChunk>
</ServerData>
要求接收标签最后一个事件的最大值时间(单位为ticks)"History":
<History>
<Value>...</Value>
</History>.
标签 "History" 可以为空:
<History></History>.
解析:
...
char* ch = new char[xml.size()+1];
std::copy(xml.begin(), xml.end(), ch);
ch[xml.size()] = '[=14=]';
xml_document<char> doc;
doc.parse<0>(ch);
unsigned long LastEventTime = 0;
xml_node<> *root_node = doc.first_node("ServerData");
for (xml_node<> * chunk_node = root_node->first_node("NetJobChunk"); chunk_node; chunk_node = chunk_node->next_sibling())
{
// History
unsigned long result = ParseChunkLastEventTime(chunk_node);
if(result > LastEventTime)
LastEventTime = result;
}
...
unsigned long CRapidXmlParser::ParseChunkLastEventTime(xml_node<char>* chunk_node) {
unsigned long val = 0;
if(chunk_node == nullptr)
throw std::exception("ParseChunkLastEventTime: null ptr chunk_node");
xml_node<> * chunk_hist_node = chunk_node->first_node("History");
xml_node<> * last_value_node = chunk_hist_node->last_node("Value");// ERROR!!!
if(last_value_node) {
std::string last_event = last_value_node->value();
size_t time_begin = last_event.find_first_of('|');
if(time_begin != std::string::npos) {
size_t time_end = last_event.find_first_of('|', time_begin+1);
if(time_end != std::string::npos) {
val = boost::lexical_cast<unsigned long>(last_event.substr(time_begin+1, time_end-time_begin-1) );
}
}
}
return val;
}
当我尝试获取空标签的最后一个子标签 ("Value") 时 "History" - 我得到一个异常,而不是预期的空指针。有什么问题?
需要使用first_node(),检查节点是否有子节点。
unsigned long CRapidXmlParser::ParseChunkLastEventTime(xml_node<char>* chunk_node) {
unsigned long val = 0;
if(chunk_node == nullptr)
throw std::exception("ParseChunkLastEventTime: null ptr chunk_node");
xml_node<> * chunk_hist_node = chunk_node->first_node("History");
if(chunk_hist_node->first_node("Value")) {
xml_node<> * last_value_node = chunk_hist_node->last_node("Value");
if(last_value_node) {
std::string last_event = last_value_node->value();
size_t time_begin = last_event.find_first_of('|');
if(time_begin != std::string::npos) {
size_t time_end = last_event.find_first_of('|', time_begin+1);
if(time_end != std::string::npos) {
val = boost::lexical_cast<unsigned long>(last_event.substr(time_begin+1, time_end-time_begin-1) );
}
}
}
}
return val;
}