如何使用RapidXML c ++检查xml中的空标记

时间:2015-08-06 04:51:15

标签: c++ xml xml-parsing rapidxml

存在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>

需要接收标签“历史记录”的最后一个事件的最大值时间(以刻度表示):

<History>
   <Value>...</Value>
</History>.

标记“历史记录”可以为空:

<History></History>.

解析:

...
char* ch = new char[xml.size()+1];
std::copy(xml.begin(), xml.end(), ch);
ch[xml.size()] = '\0';

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;
}

当我试图获取空标记“History”的最后一个子标记(“Value”)时 - 我得到一个异常,而不是预期的空指针。有什么问题?

1 个答案:

答案 0 :(得分:1)

需要使用first_node()来检查节点是否有子节点。

mysqldiff --server1=username:password@hostname:3307 --server2=username:pasword@localhost:3306 DB1:DB1 --force --difftype=sql --changes-for=server2

mysqldbcompare --server1=username:password@hostname:3307 --server2=username:pasword@localhost:3306 DB1:DB1 --run-all-test --difftype=sql changes-for=server2