2011-01-27 48 views
3

XPath查詢我們想要得到的線pugixml XPath查詢結果/列的列:獲取線/英寸Pugixml

pugi::xpath_query query_child(query_str); 
std::string value = Convert::toString(query_child.evaluate_string(root_node)); 

我們可以檢索的偏移量,而不是行/列:

unsigned int = query_child.result().offset; 

如果我們重新解析文件,我們可以轉換offset =>(行,列),但效率不高。

有沒有高效方法來實現這個?

回答

2
  1. result()。offset是查詢字符串中的最後一個解析偏移量;如果查詢成功解析,它將等於0;所以這不是XML文件中的偏移量。

  2. 對於返回字符串的XPath查詢,沒有定義「XML文件中的偏移量」的概念 - 即您對concat("a", "b")查詢有什麼期望?

  3. 對於返回節點的XPath查詢,您可以獲取文件中節點數據的偏移量。不幸的是,由於解析性能和內存消耗的原因,這些信息無法在沒有重新分析的情況下獲得。 TODO列表中有一項任務使其更容易(即使用幾行代碼),但這需要一段時間。

因此,假設你想找到的XPath查詢的結果節點的偏移,唯一的辦法是讓XPath查詢結果作爲節點集(query.evaluate_node_setnode.select_single_node/select_nodes),得到的偏移量(node.offset_debug() )並將其手動轉換爲行/列。

您可以爲偏移 - >行/列轉換準備一次數據結構,然後多次使用它;例如,下面的代碼應該工作:

#include <vector> 
#include <algorithm> 
#include <cassert> 
#include <cstdio> 

typedef std::vector<ptrdiff_t> offset_data_t; 

bool build_offset_data(offset_data_t& result, const char* file) 
{ 
    FILE* f = fopen(file, "rb"); 
    if (!f) return false; 

    ptrdiff_t offset = 0; 

    char buffer[1024]; 
    size_t size; 

    while ((size = fread(buffer, 1, sizeof(buffer), f)) > 0) 
    { 
     for (size_t i = 0; i < size; ++i) 
      if (buffer[i] == '\n') 
       result.push_back(offset + i); 

     offset += size; 
    } 

    fclose(f); 

    return true; 
} 

std::pair<int, int> get_location(const offset_data_t& data, ptrdiff_t offset) 
{ 
    offset_data_t::const_iterator it = std::lower_bound(data.begin(), data.end(), offset); 
    size_t index = it - data.begin(); 

    return std::make_pair(1 + index, index == 0 ? offset : offset - data[index - 1]); 
} 

這不處理Mac風格的換行符,不處理製表符;當然,這可以被輕微添加。

+0

謝謝,是的,我想找到節點的偏移量。 但問題是如何轉換爲行/列而無需重新解析? 也許我必須編輯pugixml代碼? – 2011-01-27 16:45:36