4

XML Like 文字列を C# または SQL のトークンに分割したいと考えています。たとえば、入力文字列は次のようになります

<entry><AUTHOR>C. Qiao</AUTHOR> and <AUTHOR>R.Melhem</AUTHOR>, "<TITLE>Reducing Communication </TITLE>",<DATE>1995</DATE>. </entry>

そして、私はこの出力が欲しい:

C       AUTHOR
.       AUTHOR
Qiao    AUTHOR
and 
R       AUTHOR
.       AUTHOR
Melhem  AUTHOR
,   
"
Reducing        TITLE
Communication   TITLE
"
,
1995    DATE
.
4

2 に答える 2

1

これは、次の点を考慮して、この問題を解決するための最初の試みです:
1. XML 文字列は有効です (つまり、タグ間に無効な文字はありません)

string xml = @"<ENTRY><AUTHOR>C. Qiao</AUTHOR>
                                  <AUTHOR>R.Melhem</AUTHOR>
                                  <TITLE>Reducing Communication </TITLE>
                                  <DATE>1995</DATE>
                           </ENTRY>";

2. 分割はスペース単位で行います' '

string xml = @"<ENTRY><AUTHOR>C. Qiao</AUTHOR>
                              <AUTHOR>R.Melhem</AUTHOR>
                              <TITLE>Reducing Communication </TITLE>
                              <DATE>1995</DATE>
                       </ENTRY>";
        XElement doc = XElement.Parse(xml);
        foreach (XElement element in doc.Elements())
        {

            var values = element.Value.Split(' ');
            foreach (string value in values)
            {
                Console.WriteLine(element.Name + " " + value);
            }
        }

印刷します

AUTHOR C.
AUTHOR Qiao
AUTHOR R.Melhem
TITLE Reducing
TITLE Communication
TITLE
DATE 1995

編集:

さて、「。」に基づいて分割します。とスペース、最良のアイデアは正規表現を使用することです。このような:

   var values = Regex.Split(element.Value, @"(\.| )");
        foreach (string value in values.Where(x=>!String.IsNullOrWhiteSpace(x)))
        {
            Console.WriteLine(element.Name + " " + value);
        }   

必要に応じて、さらに区切り記号を追加できます。次の例では、次のようになります。

AUTHOR C
AUTHOR .
AUTHOR Qiao
AUTHOR R
AUTHOR .
AUTHOR Melhem
TITLE Reducing
TITLE Communication
DATE 1995

Edit2:
そして、元の文字列で機能する例を次に示します。トークンの正しい順序がないため、おそらく最善のアプローチではありませんが、かなり近いはずです:

 string xml = @" <entry>
                            <AUTHOR>C. Qiao</AUTHOR> 
                            and 
                            <AUTHOR>R.Melhem</AUTHOR>, 
                            ""<TITLE>Reducing Communication </TITLE>""
                           ,<DATE>1995</DATE>. 
                           </entry>";
            //Parse xml to XDocument
            XDocument doc = XDocument.Parse(xml);

            // Get first element (we only have one)
            XElement element = doc.Descendants().FirstOrDefault();

            //Create a copy of an element for use by child elements.
            XElement copyElement = new XElement(element);
            //Remove all child nodes from root leaving only text
            element.Elements().Remove();

            //Splitting based on the tokens specified
                var values = Regex.Split(element.Value, @"(\.| |\,|\"")");
                    foreach (string value in values.Where(x => !String.IsNullOrWhiteSpace(x)))
                    {
                        Console.WriteLine(value);
                    }
            //Getting children nodes and splitting the same way
            foreach (XElement elem in copyElement.Elements())
            {
                var val = Regex.Split(elem.Value, @"(\.| |\,|\"")");
                foreach (string value in val.Where(x => !String.IsNullOrWhiteSpace(x)))
                {
                    Console.WriteLine(value + " " + elem.Name);
                }
            }
            //You can try to play with DescendantsAndSelf 
            //to see if you can do it in single action and with order preserved.
            //foreach (XElement elem in element.DescendantsAndSelf())
            //{
            //    //....
            //}   

これにより、次のように出力されます。

and
,
"
"
,
.
C AUTHOR
. AUTHOR
Qiao AUTHOR
R AUTHOR
. AUTHOR
Melhem AUTHOR
Reducing TITLE
Communication TITLE
1995 DATE
于 2012-12-03T06:09:12.183 に答える
0

編集:質問を間違って読んだことに気付きました-質問からではなく最初の回答からフォーマットされたXMLをコピーしたため、文字列内の混合コンテンツノードに気づきませんでした。これにより、簡単になります。ソリューションは次のようになります。

using System;
using System.Linq;
using System.Text;

using System.Xml;
using System.Xml.Linq;

class Program
{
    static void Main(string[] args)
    {
        var xml = @"<entry><AUTHOR>C. Qiao</AUTHOR> and <AUTHOR>R.Melhem</AUTHOR>, ""<TITLE>Reducing Communication </TITLE>"",<DATE>1995</DATE>. </entry>";

        var elem = XElement.Parse(xml);

        var tokFunc = new Func<XNode, string>(node =>
            {
                var s = node.ToString().Replace(".", " . ").Replace(",", " , ");
                var nodeName = node.Parent != null && 
                    node.Parent.NodeType == XmlNodeType.Element && 
                    node.Parent.Name.LocalName.ToUpper() != "ENTRY"
                                   ? node.Parent.Name.LocalName
                                   : "";
                var sb = new StringBuilder();

                s.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach(e => sb.AppendFormat("{0}\t{1}\n", e, nodeName));
                return sb.ToString();
            });


        elem.DescendantNodes().Where(e => e.NodeType == XmlNodeType.Text).ToList()
            .ForEach(c => Console.Write(tokFunc(c)));


    }
}

これにより、目的の出力が生成されます。

C       AUTHOR
.       AUTHOR
Qiao    AUTHOR
and
R       AUTHOR
.       AUTHOR
Melhem  AUTHOR
,
"
Reducing        TITLE
Communication   TITLE
"
,
1995    DATE
.
于 2012-12-03T07:11:36.857 に答える