title: How check empty tag in xml with RapidXML c++
body: <p><strong>Exists XML:</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;ServerData&gt;
      &lt;NetJobChunk id="599"&gt;
          &lt;Frames&gt;0.000 - 0.000&lt;/Frames&gt;
          &lt;EndTime&gt;0&lt;/EndTime&gt;
          &lt;ChunkID&gt;1&lt;/ChunkID&gt;
          &lt;StartDateTime&gt;42212.713495&lt;/StartDateTime&gt;
          &lt;RenderedFiles&gt;&lt;/RenderedFiles&gt;
          &lt;AttemptsText&gt;0&lt;/AttemptsText&gt;
          &lt;RenderingTimeText&gt;n/a&lt;/RenderingTimeText&gt;
          &lt;Slice&gt;Entire image&lt;/Slice&gt;
          &lt;Attempts&gt;0&lt;/Attempts&gt;
          &lt;ErrorCount&gt;0&lt;/ErrorCount&gt;
          &lt;StartDateText&gt;27.07.2015 17:07:26&lt;/StartDateText&gt;
          &lt;RenderingClient&gt;&lt;/RenderingClient&gt;
          &lt;Priority&gt;0&lt;/Priority&gt;
          &lt;StartTime&gt;0&lt;/StartTime&gt;
          &lt;NetJobID&gt;599&lt;/NetJobID&gt;
          &lt;ExtSplitting&gt;None&lt;/ExtSplitting&gt;
          &lt;AvgCPUUsage&gt;0.000000&lt;/AvgCPUUsage&gt;
          &lt;RenderingClientUuid&gt;00000000-0000-0000-0000-000000000000&lt;/RenderingClientUuid&gt;
          &lt;History&gt;&lt;/History&gt;
          &lt;CacheScenesLocally&gt;false&lt;/CacheScenesLocally&gt;
          &lt;RenderingTime&gt;0&lt;/RenderingTime&gt;
          &lt;RecacheScenes&gt;false&lt;/RecacheScenes&gt;
          &lt;StateMachineState&gt;0&lt;/StateMachineState&gt;
          &lt;Scene&gt;P:\\ftpuser\\F20141088\\Scene_news\\3dsmax\\test.max&lt;/Scene&gt;
          &lt;StatusText&gt;Done&lt;/StatusText&gt;
          &lt;Status&gt;4&lt;/Status&gt;
      &lt;/NetJobChunk&gt;
  
      &lt;NetJobChunk id="599"&gt;
          &lt;Frames&gt;1.000 - 1.000&lt;/Frames&gt;
          &lt;EndTime&gt;0&lt;/EndTime&gt;
          &lt;ChunkID&gt;2&lt;/ChunkID&gt;
          &lt;StartDateTime&gt;42212.713495&lt;/StartDateTime&gt;
          &lt;RenderedFiles&gt;&lt;/RenderedFiles&gt;
          &lt;AttemptsText&gt;0&lt;/AttemptsText&gt;
          &lt;RenderingTimeText&gt;n/a&lt;/RenderingTimeText&gt;
          &lt;Slice&gt;Entire image&lt;/Slice&gt;
          &lt;Attempts&gt;0&lt;/Attempts&gt;
          &lt;ErrorCount&gt;0&lt;/ErrorCount&gt;
          &lt;StartDateText&gt;27.07.2015 17:07:26&lt;/StartDateText&gt;
          &lt;RenderingClient&gt;&lt;/RenderingClient&gt;
          &lt;Priority&gt;0&lt;/Priority&gt;
          &lt;StartTime&gt;0&lt;/StartTime&gt;
          &lt;NetJobID&gt;599&lt;/NetJobID&gt;
          &lt;ExtSplitting&gt;None&lt;/ExtSplitting&gt;
          &lt;AvgCPUUsage&gt;0.000000&lt;/AvgCPUUsage&gt;
          &lt;RenderingClientUuid&gt;00000000-0000-0000-0000-000000000000&lt;/RenderingClientUuid&gt;
          &lt;History&gt;&lt;/History&gt;
          &lt;CacheScenesLocally&gt;false&lt;/CacheScenesLocally&gt;
          &lt;RenderingTime&gt;0&lt;/RenderingTime&gt;
          &lt;RecacheScenes&gt;false&lt;/RecacheScenes&gt;
          &lt;StateMachineState&gt;0&lt;/StateMachineState&gt;
          &lt;Scene&gt;P:\\ftpuser\\F20141088\\Scene_news\\3dsmax\\test.max&lt;/Scene&gt;
          &lt;StatusText&gt;Done&lt;/StatusText&gt;
          &lt;Status&gt;4&lt;/Status&gt;
      &lt;/NetJobChunk&gt;
  
      &lt;NetJobChunk id="601"&gt;
          &lt;Frames&gt;0.000 - 0.000&lt;/Frames&gt;
          &lt;EndTime&gt;0&lt;/EndTime&gt;
          &lt;ChunkID&gt;1&lt;/ChunkID&gt;
          &lt;StartDateTime&gt;42212.852882&lt;/StartDateTime&gt;
          &lt;RenderedFiles&gt;&lt;/RenderedFiles&gt;
          &lt;AttemptsText&gt;1 (max)&lt;/AttemptsText&gt;
          &lt;RenderingTimeText&gt;n/a&lt;/RenderingTimeText&gt;
          &lt;Slice&gt;Entire image&lt;/Slice&gt;
          &lt;Attempts&gt;1&lt;/Attempts&gt;
          &lt;ErrorCount&gt;1&lt;/ErrorCount&gt;
          &lt;StartDateText&gt;&lt;/StartDateText&gt;
          &lt;RenderingClient&gt;&lt;/RenderingClient&gt;
          &lt;Priority&gt;0&lt;/Priority&gt;
          &lt;StartTime&gt;0&lt;/StartTime&gt;
          &lt;NetJobID&gt;601&lt;/NetJobID&gt;
          &lt;ExtSplitting&gt;Camera: 005&lt;/ExtSplitting&gt;
          &lt;AvgCPUUsage&gt;0.000000&lt;/AvgCPUUsage&gt;
          &lt;RenderingClientUuid&gt;00000000-0000-0000-0000-000000000000&lt;/RenderingClientUuid&gt;
          &lt;History&gt;
              &lt;Value&gt;1|1437999253|Rendering started [RENDERHOST202]|&lt;/Value&gt;
              &lt;Value&gt;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.|&lt;/Value&gt;
              &lt;Value&gt;4|1438010888|Chunk error: The renderer returned an error-code (0x3) [RENDERHOST202]|&lt;/Value&gt;
              &lt;Value&gt;1|1438010889|Rendering started [RENDERHOST202]|&lt;/Value&gt;
              &lt;Value&gt;3|1438017456|Chunk cancelled [RENDERHOST202]|&lt;/Value&gt;
              &lt;Value&gt;3|1438017456|Net Job cancelled by user|&lt;/Value&gt;
          &lt;/History&gt;
          &lt;CacheScenesLocally&gt;false&lt;/CacheScenesLocally&gt;
          &lt;RenderingTime&gt;0&lt;/RenderingTime&gt;
          &lt;RecacheScenes&gt;false&lt;/RecacheScenes&gt;
          &lt;StateMachineState&gt;0&lt;/StateMachineState&gt;
          &lt;Scene&gt;P:\\ftpuser\\F20131020\\2House_22_2015_07_27_12_16_55\\2House_22.max&lt;/Scene&gt;
          &lt;StatusText&gt;Cancelled&lt;/StatusText&gt;
          &lt;Status&gt;5&lt;/Status&gt;
      &lt;/NetJobChunk&gt;
  
  &lt;/ServerData&gt;
  </code></pre>
  
  <p>It is required to receive the maximum value time (in ticks) of the last event of the tag "History":</p>
  
  <pre><code>&lt;History&gt;
     &lt;Value&gt;...&lt;/Value&gt;
  &lt;/History&gt;.
  </code></pre>
  
  <p>Tag "History" can be empty:</p>
  
  <pre><code>&lt;History&gt;&lt;/History&gt;.
  </code></pre>
  
  <p><strong>Parsing:</strong></p>
  
  <pre><code>...
  char* ch = new char[xml.size()+1];
  std::copy(xml.begin(), xml.end(), ch);
  ch[xml.size()] = '\0';
  
  xml_document&lt;char&gt; doc;
  doc.parse&lt;0&gt;(ch);
  unsigned long LastEventTime = 0;
  
  xml_node&lt;&gt; *root_node = doc.first_node("ServerData");
  for (xml_node&lt;&gt; * chunk_node = root_node-&gt;first_node("NetJobChunk"); chunk_node; chunk_node = chunk_node-&gt;next_sibling())
  {
      // History
      unsigned long result = ParseChunkLastEventTime(chunk_node);
      if(result &gt; LastEventTime)
          LastEventTime = result;
  
  }
  </code></pre>
  
  <p>...</p>
  
  <pre><code>unsigned long CRapidXmlParser::ParseChunkLastEventTime(xml_node&lt;char&gt;* chunk_node) {
      unsigned long val = 0;
      if(chunk_node == nullptr)
          throw std::exception("ParseChunkLastEventTime: null ptr chunk_node");
  
      xml_node&lt;&gt; * chunk_hist_node = chunk_node-&gt;first_node("History");
      xml_node&lt;&gt; * last_value_node = chunk_hist_node-&gt;last_node("Value");// ERROR!!!
      if(last_value_node) {
          std::string last_event = last_value_node-&gt;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&lt;unsigned long&gt;(last_event.substr(time_begin+1, time_end-time_begin-1) );
              }
          } 
      }
  
      return val;
  }
  </code></pre>
  
  <p>When I'm trying to get the last child tag ("Value") of an empty tag "History" - I get an exception, instead of the expected null pointer. What is the problem?</p>