SlimXml的一个使用注意点
【摘要】 setString/getString特殊字符不会自动转义
-----后来发现有个SLIM_TRANSFER_CHARACTER宏,开启即可
assignString函数运行报错,修正为
setString/getString特殊字符不会自动转义
-----后来发现有个SLIM_TRANSFER_CHARACTER宏,开启即可
assignString函数运行报错,修正为
setString(temp); //memcpy(str, temp.c_str(), sizeof(Char) * actualLength); //str[actualLength] = 0;
buffer = const_cast<slim::Char*>(found + 1); if (length >= 6) { if (Strncmp(buffer, T("quot;"), 5) == 0)//此外转义符号里面没有分号,类似我也处理一下
下面是rapidxml中的转义和解转义方法
转义
// Copy characters from given range to given output iterator and expand // characters into references (< > ' " &) template<class OutIt, class Ch> inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out) { while (begin != end) { if (*begin == noexpand) { *out++ = *begin; // No expansion, copy character } else { switch (*begin) { case Ch('<'): *out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';'); break; case Ch('>'): *out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';'); break; case Ch('\''): *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';'); break; case Ch('"'): *out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';'); break; case Ch('&'): *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';'); break; default: *out++ = *begin; // No expansion, copy character } } ++begin; // Step to next character } return out; }
解转义
// Skip characters until predicate evaluates to true while doing the following: // - replacing XML character entity references with proper characters (' & " < > &#...;) // - condensing whitespace sequences to single space character template<class StopPred, class StopPredPure, int Flags> static Ch *skip_and_expand_character_refs(Ch *&text) { // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip if (Flags & parse_no_entity_translation && !(Flags & parse_normalize_whitespace) && !(Flags & parse_trim_whitespace)) { skip<StopPred, Flags>(text); return text; } // Use simple skip until first modification is detected skip<StopPredPure, Flags>(text); // Use translation skip Ch *src = text; Ch *dest = src; while (StopPred::test(*src)) { // If entity translation is enabled if (!(Flags & parse_no_entity_translation)) { // Test if replacement is needed if (src[0] == Ch('&')) { switch (src[1]) { // & ' case Ch('a'): if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';')) { *dest = Ch('&'); ++dest; src += 5; continue; } if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s') && src[5] == Ch(';')) { *dest = Ch('\''); ++dest; src += 6; continue; } break; // " case Ch('q'): if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t') && src[5] == Ch(';')) { *dest = Ch('"'); ++dest; src += 6; continue; } break; // > case Ch('g'): if (src[2] == Ch('t') && src[3] == Ch(';')) { *dest = Ch('>'); ++dest; src += 4; continue; } break; // < case Ch('l'): if (src[2] == Ch('t') && src[3] == Ch(';')) { *dest = Ch('<'); ++dest; src += 4; continue; } break; // &#...; - assumes ASCII case Ch('#'): if (src[2] == Ch('x')) { unsigned long code = 0; src += 3; // Skip &#x while (1) { unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)]; if (digit == 0xFF) break; code = code * 16 + digit; ++src; } insert_coded_character<Flags>(dest, code); // Put character in output } else { unsigned long code = 0; src += 2; // Skip &# while (1) { unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)]; if (digit == 0xFF) break; code = code * 10 + digit; ++src; } insert_coded_character<Flags>(dest, code); // Put character in output } if (*src == Ch(';')) ++src; else RAPIDXML_PARSE_ERROR("expected ;", src); continue; // Something else default: // Ignore, just copy '&' verbatim break; } } } // If whitespace condensing is enabled if (Flags & parse_normalize_whitespace) { // Test if condensing is needed if (whitespace_pred::test(*src)) { *dest = Ch(' '); ++dest; // Put single space in dest ++src; // Skip first whitespace char // Skip remaining whitespace chars while (whitespace_pred::test(*src)) ++src; continue; } } // No replacement, only copy character *dest++ = *src++; } // Return new end text = src; return dest; }
为slimxml添加相关转义的功能
void escape(std::wstring& xml) std::map<wchar_t, std::wstring> transformations; transformations[L'&'] = std::wstring(L"&"); transformations[L'\''] = std::wstring(L"'"); transformations[L'"'] = std::wstring(L"""); transformations[L'>'] = std::wstring(L">"); transformations[L'<'] = std::wstring(L"<"); // Build list of characters to be searched for. // std::string reserved_chars; for (auto ti = transformations.begin(); ti != transformations.end(); ti++) { reserved_chars += ti->first; } size_t pos = 0; while (std::wstring::npos != (pos = xml.find_first_of(reserved_chars, pos))) { xml.replace(pos, 1, transformations[xml[pos]]); pos++; } } //================================= void replace_all(std::string& str, const std::string& old, const std::string& repl) { size_t pos = 0; while ((pos = str.find(old, pos)) != std::string::npos) { str.replace(pos, old.length(), repl); pos += repl.length(); } } std::string escape_xml(std::string str) { replace_all(str, std::string("&"), std::string("&")); replace_all(str, std::string("'"), std::string("'")); replace_all(str, std::string("\""), std::string(""")); replace_all(str, std::string(">"), std::string(">")); replace_all(str, std::string("<"), std::string("<")); return str; } //======================== std::string unescape_xml(std::string str) { replace_all(str, std::string("&"), std::string("&")); replace_all(str, std::string("'"), std::string("'")); replace_all(str, std::string("""), std::string("\"")); replace_all(str, std::string(">"), std::string(">")); replace_all(str, std::string("<"), std::string("<")); return str; }
需要好好考虑的是怎么修改才能避免应该解析和格式化的效率;
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)