2

完全なノード (サブノードを含む) をテキストとして読み取る単純な XMLreader を作成したいと思います。

string TXML = @"<xml><text>hall&#xF6;le</text></xml>";

XmlReader r = XmlReader.Create(new StringReader(TXML));
r.Read(); r.Read();

string o = r.ReadOuterXml();

ReadOuterXml仕事をしますが、すでにエスケープされた記号をエスケープしません:

"<text>hallöle</text>"

私は結果を望んでいます:

"<text>hall&#xF6;le</text>"

どうすればその「エスケープ解除」を省略できますか。このフラグメントをデータベースに保存したいのですが、そのエスケープが必要です。さらに、フラグメントを解析して再作成したくありません。

4

4 に答える 4

3

同様の問題がありました。xmlから読み取るときにエスケープ文字を保持したかったのですが、ReadOuterXml()を呼び出すときに、一部の文字のみが保持され、少なくともoaneが変換されました(「」ではなく「」を見出します)

私の解決策は次のとおりです。

string TXML = @"<xml><text>hall&#xF6;le</text></xml>";
TXML = TXML.Replace("&", "&amp;");
XmlTextReader r = new XmlTextReader(new StringReader(TXML));
r.Read(); r.Read();
// now we are at the text element
r.ReadStartElement()
var content = SecurityElement.Escape(r.ReadContentAsString())
r.ReadEndElement()
于 2012-11-14T13:11:31.433 に答える
2

私は2つの解決策を見つけました。どちらもあまり良くありませんが、欠点が少ない方を教えてください.

どちらのソリューションも、「XmlReader」の代わりに「XmlTextReader」を直接使用することに依存しています。それには、最初のソリューションにつながるプロパティ「LinePosition」と、2 番目のソリューションの基礎としてメソッド「ReadChars」が付属しています。

解決策 (1)、インデックスを介して元の文字列からデータを取得する

問題:

  • ストリーム入力では機能しません
  • xml に複数の行がある場合は機能しません

コード

string TXML = @"<xml><data></data><rawnode at=""10 4""><text>hall&#xF6;le</text><z d=""2"">3</z></rawnode><data></data></xml>";

//XmlReader r = XmlReader.Create(new StringReader(TXML));
XmlTextReader r = new XmlTextReader(new StringReader(TXML));

// read to node which shall be retrived "raw"
while ( r.Read() )
{
    if ( r.Name.Equals("rawnode") )
        break;
}

// here we start
int Begin = r.LinePosition;
r.Skip();
int End = r.LinePosition;

// get it out
string output=TXML.Substring(Begin - 2, End - Begin);

解決策 (2)、「ReadChars」でデータを取得する

問題:

  • 読み取りたいタグの「外側」マークアップを解析して再作成する必要があります。
  • これにより、パフォーマンスが低下する可能性があります。
  • エラーが発生する可能性があります。

コード:

// ... again create XmlTextReader and read to rawnode, then:
// here we start
int buflen = 15;
char[] buf = new char[buflen];
StringBuilder sb= new StringBuilder("<",20);

//get start tag and attributes    
string tagname=r.Name;
sb.Append(tagname);
bool hasAttributes = r.MoveToFirstAttribute();
while (hasAttributes)
{
    sb.Append(" " + r.Name + @"=""" + r.Value + @"""");
    hasAttributes = r.MoveToNextAttribute();
}
sb.Append(@">");
r.MoveToContent();

//get raw inner data    
int cnt;
while ((cnt = r.ReadChars(buf, 0, buflen)) > 0)
{
    if ( cnt<buflen )
        buf[cnt]=(char)0;
    sb.Append(buf);
}

//append end tag    
sb.Append("</" + tagname + ">");

// get it out
string output = sb.ToString();
于 2012-05-23T14:42:46.980 に答える
1

xml ヘッダーを見て、次のようなものが含まれていることを確認します。<?xml version="1.0" encoding="ISO-8859-9"?>

InnerXmlエスケープとアンエスケープには、c# 関数とInnerText次を使用できます。

public static string XmlEscape(string unescaped)
{
    XmlDocument doc = new XmlDocument();
    var node = doc.CreateElement("root");
    node.InnerText = unescaped;
    return node.InnerXml;
}

public static string XmlUnescape(string escaped)
{
    XmlDocument doc = new XmlDocument();
    var node = doc.CreateElement("root");
    node.InnerXml = escaped;
    return node.InnerText;
}
于 2012-05-22T14:53:17.790 に答える
0

エスケープされた文字を解析して再作成する必要がないようにというあなたの希望は理解していますが、それを完全にカスタマイズしない限り、そうしない方法を見つけることができません。もしかしてこれは悪くない?

string TXML = @"<xml><text>hall&#xF6;le</text></xml>";
TXML = TXML.Replace("&", "&amp;");
XmlTextReader r = new XmlTextReader(new StringReader(TXML));
r.Read(); r.Read();

string o = r.ReadOuterXml();
o = o.Replace("&amp;", "&");
于 2012-05-22T15:25:35.600 に答える