xml搜尋

Prerequisites:

要在一堆xml內容中尋找標籤名為name,並取出值。

<id>1</id><name>Cici</name><age>10</age>

思路

組成name開始標籤與結束標籤

自已建立<name>字串,並在xml中尋找是否有相同的字串,函式會傳回<name>起始位址。

xml < n a m e >
傳回位址 ^          

自已建立</name>字串,並在xml中尋找是否有相同的字串,函式會傳回</name>起始位址。

xml < n a m e > C i c i < / n a m e >
傳回位址                     ^            

計算值的字元個數

假設位址以0x00000001開始

位址 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17
xml < n a m e > C i c i < / n a m e >
findEnd                     ^            
findStart ^                                

值的字元個數計算方式,取得findEnd記憶體位址 - findStart記憶體位址 - 左右括號 - 標籤名

findEnd(11) - findStart(1) - `<>`左右括號(2) - xml標籤名name(4) = 4 
1
size_t valueLen = findEnd - findStart - fieldLen - 2;

截取值

指標移動2格<>左右括號,再移動4格name標籤名的長度,就會移動到值的起始位址。

上一個步驟有算出,值的長度為4個字元,從移動後的指標,往後取得4個字元(包含移動後指標當前的值)。

位址 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17
xml < n a m e > C i c i < / n a m e >
移動前 ^                                
移動後             ^                    
取值             x x x x              
1
strncpy(values, findStart + 2 + fieldLen , valueLen);

完整程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/**
 xmlbuffer xml字串
 fieldname 要搜尋的 標籤名
 values存放找到的值
 **/
bool xmlSearch(const char* xmlbuffer, const char* fieldname, char* values) {
  //檢查參數有沒有值
  if(xmlbuffer == 0 || fieldname == 0 || values == 0) return false;
  
  //搜尋的欄位名大小
  size_t fieldLen = strlen(fieldname);
  //組成xml搜尋字串
  //例,找xml標籤名是name的值
  //開始 標籤名的字串
  //<name>\0
  //字串大小為2個<>尖括號+1個結尾空字元0+標籤名name大小
  char* startField = new char[2 + 1 + fieldLen];
  //清空陣列
  memset(startField, 0, sizeof(startField));
  strcpy(startField, "<"); strcat(startField, fieldname); strcat(startField, ">");
  //結束 標籤名的字串
  //</name>\0
  //字串大小為3個</>符號+1個結尾空字元0+標籤名name大小
  char* endField = new char[3 + 1 + fieldLen];
  //清空陣列
  memset(endField, 0, sizeof(endField));
  strcpy(endField, "</"); strcat(endField, fieldname); strcat(endField, ">");
  //搜<name>
  char* findStart = (char*)strstr(xmlbuffer, startField);
  //搜</name>
  char* findEnd = (char*)strstr(xmlbuffer, endField);
  //在xml字串中找到<name>與</name>
  if(findStart && findEnd) {
    //截取<name>.......</name>中間的值,儲存在value字串
    //計算<name>.......</name>中間的值個數
    size_t valueLen = findEnd - findStart - fieldLen - 2;
    //findStart + 2 + fieldLen 是指將指標移動到<name>的後面
    //以下第三個參數代表拷貝個數
    strncpy(values, findStart + 2 + fieldLen , valueLen);
    
    //清除記憶空間
    delete[] startField; startField = nullptr;
    delete[] endField; endField = nullptr;
    return true;
  }
  //找不到
  //清除記憶空間
  delete[] startField; startField = nullptr;
  delete[] endField; endField = nullptr;
  return false;
}
int main() {
  char values[100];
  //清空陣列
  memset(values, 0, sizeof(values));
  
  bool res = xmlSearch("<id>1</id><name>Cici</name><age>10</age>", "name", values);
  //如果有找到會傳回true
  if(res) {
    cout << "value = " << values << endl;
  }
  return 0;
}
value = Cici

results matching ""

    No results matching ""