2012-03-28 1 views
5

ウェブをたくさん探して、xmlの特殊文字をエスケープシーケンスに置き換えるC++関数が見つかりませんでしたか? ありますか?xml特殊文字をエスケープシーケンスに置き換えるC++関数はありますか?

私は、次の知っている:

Special Character Escape Sequence Purpose 
&     &   Ampersand sign 
'     '   Single quote 
"     "   Double quote 
>     >   Greater than 
<     &lt;   Less than 

がもっとありますか? 0×00、 のように16進値を書くのはどうですか?これも問題ですか?関数が

+0

なぜあなたはそれを自分で行うのですか? 5文字列が例えば –

+0

に置き換わる@stefanbachertまず、特殊文字、lkeの外国語と通貨記号があることを知っています。私はエンコードを二重にしたくない。なぜホイールを発明するのか?おそらく、私が慣れていないことを考えている人がいるかもしれません。 –

+2

上記の5つのデフォルトの特殊エンティティは、xml自体で定義されています。他のエンティティは、doctypeまたはスキーマによって定義されることがあります。結局、誰もがエンティティを定義することができました。だから、あなたは標準的な機能を見つけることはできません。 –

答えて

6

前述したように、あなた自身で書くことができます。 exampleの場合:

#include <iostream> 
#include <string> 
#include <map> 

int main() 
{ 
    std::string xml("a < > & ' \" string"); 
    std::cout << xml << "\n"; 

    // Characters to be transformed. 
    // 
    std::map<char, std::string> transformations; 
    transformations['&'] = std::string("&amp;"); 
    transformations['\''] = std::string("&apos;"); 
    transformations['"'] = std::string("&quot;"); 
    transformations['>'] = std::string("&gt;"); 
    transformations['<'] = std::string("&lt;"); 

    // 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::string::npos != (pos = xml.find_first_of(reserved_chars, pos))) 
    { 
     xml.replace(pos, 1, transformations[xml[pos]]); 
     pos++; 
    } 

    std::cout << xml << "\n"; 

    return 0; 
} 

が出力:

a < > & ' " string 
a &lt; &gt; &amp; &apos; &quot; string 

新しい変換を導入するtransformationsにエントリを追加します。あなた自身を書く

2

があり、私はつまり、それを書いた:

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("&amp;")); 
    replace_all(str, std::string("'"), std::string("&apos;")); 
    replace_all(str, std::string("\""), std::string("&quot;")); 
    replace_all(str, std::string(">"), std::string("&gt;")); 
    replace_all(str, std::string("<"), std::string("&lt;")); 

    return str; 
} 
0

あなたがXMLを自分で生成することが表示されます。私はあなたがはるかに明確にする必要があると思うし、あなたが成功したい場合は、XML仕様を読んでください。それらは唯一のXML特殊文字です。あなたは「特殊文字、lkeの外国語と通貨記号があることを知っています」と言っています...コードポイントとしてコード化することを意味しない限り、これらはXMLで定義されていません(例えば&#163; )。あなたはHTMLや他のDTDを考えていますか?

二重エンコードを避ける唯一の方法は、物を一度エンコードすることです。文字列 "& gt;"を取得した場合、既にエンコードされていて、文字列 ">"を表したかったかどうかを知るか、 "& gt;"という文字列を表したいと思います。

最良の方法は、(非エンコードされた文字列として文字列を含む)DOMとしてあなたのXMLを表し、そして使用し、Xerces

ああようなXMLシリアライザすることであり、XMLに0x20の下の文字を表現する方法はありません覚えています(& x9; & xA;および& xD; - 空白)を除く)。

+0

ほとんどのxmlジェネレータとxmlリーダーは、0x20以下の文字で非常に豊富です。だからそれほど大きな問題ではないでしょう。 xml 1.1標準でも、正式にそれを受け入れます(文字参照ではなく、文字自体)。例外は0x00です。これはどんな形や形でも許されません。 –

+0

@MrListerこれを読んでhttp://seattlesoftware.wordpress.com/2008/09/11/hexadecimal-value-0-is-an-invalid-character/ –

+0

はい、この記事では、0x00文字を格納できないことが確認されていますXMLファイルを削除する方法を示します。それはあなたを助けますか? –

10

は十分に簡単ですが、検索/個々の文字を置き換えるために、複数回の文字列をスキャンすることは非効率的になります

std::string escape(const std::string& src) { 
    std::stringstream dst; 
    for (char ch : src) { 
     switch (ch) { 
      case '&': dst << "&amp;"; break; 
      case '\'': dst << "&apos;"; break; 
      case '"': dst << "&quot;"; break; 
      case '<': dst << "&lt;"; break; 
      case '>': dst << "&gt;"; break; 
      default: dst << ch; break; 
     } 
    } 
    return dst.str(); 
} 

注:私は、便宜上C++ 11の範囲ベースのforループを使用しましたしかし、イテレータで同じことを簡単に実行できます。

1

私はFerrccioのソリューションを若干修正して、< 0x20など(インターネットのどこかにある)など、途中の他の文字も削除しました。テストされ、働いています。

void strip_tags(string* s) { 
    regex kj("</?(.*)>"); 
    *s = regex_replace(*s, kj, "", boost::format_all); 

    std::map<char, std::string> transformations; 
    transformations['&'] = std::string("&amp; "); 
    transformations['\''] = std::string("&apos; "); 
    transformations['"'] = std::string("&quot; "); 
    transformations['>'] = std::string("&gt; "); 
    transformations['<'] = std::string("&lt; "); 

    // Build list of characters to be searched for. 
    // 
    std::string reserved_chars; 
    for (std::map<char, std::string>::iterator ti = transformations.begin(); ti != transformations.end(); ti++) 
    { 
     reserved_chars += ti->first; 
    } 

    size_t pos = 0; 
    while (std::string::npos != (pos = (*s).find_first_of(reserved_chars, pos))) 
    { 
     s->replace(pos, 1, transformations[(*s)[pos]]); 
     pos++; 
    } 



} 


string removeTroublesomeCharacters(string inString) 
{ 

    if (inString.empty()) return ""; 

    string newString; 
    char ch; 

    for (int i = 0; i < inString.length(); i++) 
    { 

     ch = inString[i]; 
     // remove any characters outside the valid UTF-8 range as well as all control characters 
     // except tabs and new lines 
     if ((ch < 0x00FD && ch > 0x001F) || ch == '\t' || ch == '\n' || ch == '\r') 
     { 
      newString.push_back(ch); 
     } 
    } 
    return newString; 

この場合、2つの機能があります。結果は次のようになります。

string StartingString ("Some_value"); 
string FinalString = removeTroublesomeCharacters(strip_tags(&StartingString)); 

希望すると助かります!

(そうそう:他の機能のためのクレジットはここに答えの作者に行く:How do you remove invalid hexadecimal characters from an XML-based data source prior to constructing an XmlReader or XPathDocument that uses the data?

5

機能のこれらのタイプは、標準であるべきで、私たちはそれらを書き換えする必要はありません。 VSを使用している場合は、atlenc.hをご覧ください このファイルは、VSインストールの一部です。 ファイル内にEscapeXMLという関数があります。これは上記の例よりはるかに完全です。

関連する問題