簡體   English   中英

如何使用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>

要求接收標簽“ History”的最后一個事件的最長時間(以滴答為單位):

<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”)時,出現異常,而不是預期的空指針。 問題是什么?

需要使用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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM