2017-01-24 13 views
1

親愛なるStackOverflowのメンバー、プレースホルダをXML要素に置き換えて文字列をXMLに変換します。

私はC#で働いています。

"This {1} is {2}really{3} great {4}, isn't it?" 

中括弧の間のプレースホルダは、次のタグ(配列内に含まれる)に対応するかもしれない:

ケース1:

{1} = <cf underline="single"> 
{2} = <cf bold="True"> 
{3} = </cf> 
{4} = </cf> 

又はケース2 Iは、次の文字列を有しています:

{1} = <cf underline="single"> 
{2} = </cf> 
{3} = <cf bold="True"> 
{4} = </cf> 

つまり、同じレベルのノードまたは子ノードノード。

私のセグメントにタグを挿入したいのですが、私の配列をループして、対応するプレースホルダを指定した値に置き換えることで簡単に行うことができます。それは簡単な部分です。

ケース1:

<seg> 
This 
    <cf underline="single" startID=1 endId=4> 
    is 
    <cf bold="True" startID=2 endId=3> 
    really 
    </cf> 
    great 
    </cf> 
, isn't it?" 
</seg> 

ケース しかし、私は私のXMLは次のようになりますように、開口部のIDと終了タグを含んでいるでしょうオープニング要素内の属性を挿入したいと思います2:

<seg> 
This 
    <cf underline="single" startID=1 endId=2> 
    is 
    </cf> 
    really 
    <cf bold="True" startID=3 endId=4> 
    great 
    </cf> 
, isn't it?" 
</seg> 

これを達成するためのヒントはありますか?私はこれを何時間も解決しようとしていましたが、どこから始めることさえできません。

ご協力いただきありがとうございます。

よろしく、

ローラン

+0

スタックデータ構造を使用するのはどれくらい快適ですか? – hoodaticus

+1

こんにちは@hoodaticus、私はすでにスタックを使って作業しましたが、私はこの特定のケースでどのように使用できるのか分かりません。もう一つのヒント;-)? – LaurentP

答えて

0

は、一般的に試してみて、文字列を使用してXMLを操作しないでください。それは頭痛で、あなたはそれを正しくする前に、何度もそれを捻挫します。 XmlDocumentを使用します。

テンプレートの置き換えには、文字列を使用できます。それから、XML文書に変換して、その後、あなたの属性を設定するために歩いていくことをお勧めします。このような

何か:

using System; 
using System.Xml; 

public class Program 
{ 


    public static void WalkXml(XmlElement node, ref int index) { 

     node.SetAttribute("startIndex", index.ToString()); 

     foreach(XmlNode child in node.ChildNodes) { 
      XmlElement element = (child as XmlElement); 
      if (element != null) { 
       index++; 
       WalkXml(element, ref index); 
      } 

     } 
     node.SetAttribute("endIndex", (++index).ToString()); 
    } 

    public static void WriteXml(string message, string[] tags) { 
     var xmlStr = $"<seg>{String.Format(message, tags)}</seg>"; 
     var xmlObj = new XmlDocument(); 
     xmlObj.LoadXml(xmlStr); 

     int index = 1; 
     WalkXml(xmlObj.DocumentElement, ref index);  

     Console.WriteLine(xmlObj.InnerXml); 
    } 

    public static void Main() 
    { 
     string[] tags1 = new string[] { 
      "<cf underline=\"single\">", 
      "<cf bold=\"True\">", 
      "</cf>", 
      "</cf>" 
     }; 

     string[] tags2 = new string[] { 
      "<cf underline=\"single\">", 
      "</cf>", 
      "<cf bold=\"True\">", 
      "</cf>" 
     };  

     string message = "This {0} is {1}really{2} great {3}, isn't it?"; 

     WriteXml(message, tags1); 
     WriteXml(message, tags2); 
    } 

} 

はここでデモコードは、同様に「ワンセグ」のインデックスを置く出力

<seg startIndex="1" endIndex="6">This <cf underline="single" startIndex="2" endIndex="5"> is <cf bold="True" startIndex="3" endIndex="4">really</cf> great </cf>, isn't it?</seg> 
<seg startIndex="1" endIndex="6">This <cf underline="single" startIndex="2" endIndex="3"> is </cf>really<cf bold="True" startIndex="4" endIndex="5"> great </cf>, isn't it?</seg> 

だが、それはアイデアを示し、あなたがそれに応じて調整することができるはずです。

+0

こんにちは@JamesT、ありがとうございます。あなたの答えで私は両方の場合に正しいIDを割り当てることができました。大変ありがとうございます。私はすでにロジック全体を実装しているので私は馬鹿だと感じています。唯一欠けていたのは、要素を処理した後に増加するインデックスでした。私はこれであまりにも長く働いたと思うし、明らかに見ることができませんでした。 – LaurentP

+0

心配はいりません。フレッシュな目とそのすべて。 – JamesT

0

下記のコードを試してください。あなたは本当に少し後退しています。 xmlに文字列を追加するのではなく、文字列の間にxmlを追加します。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 

namespace ConsoleApplication43 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string[] input = { "This", "is","really", "great",", isn't it?"}; 
      KeyValuePair<int, int>[] startEndId = { 
       new KeyValuePair<int,int>(1,4), 
       new KeyValuePair<int,int>(2,3) 
      }; 


      var seq = new XElement("seg", new object[] { 
       input[0], 
       new XElement("cf", new object[] { 
        new XAttribute("underline", "single"), 
        new XAttribute("startID", startEndId[0].Key), 
        new XAttribute("endID", startEndId[0].Value), 
        input[1], 
        new XElement("cf", new object[] { 
         new XAttribute("bold", "True"), 
         new XAttribute("startID", startEndId[1].Key), 
         new XAttribute("endID", startEndId[1].Value), 
         input[2], 
        }), 
        input[3], 
       }), 
       input[4] 
      }); 
     } 
    } 
} 
+0

貴重な@jdweng、あなたのソリューションに感謝します。しかし、私はJamesTのソリューションを選択しました。私は同じロジックに従っていたからですが、他の目的のためでした。あなたの助けをありがとう。 – LaurentP

関連する問題