2012-02-29 14 views
0

私は扱いたいXMLのチャンクを持っています。私はC#でこれを書いていますが、私がしたいことを説明するために擬似コードを使用します。これ以上の情報が必要な場合はお知らせください。次のようにC#では、私がXMLDocumentのにXMLを読み込む:子に影響を与えずにxmlNodesを読み込んで変更する

XmlDocument templateDoc = new XmlDocument(); 
      templateDoc.LoadXml(selectionTemplate); 
      XmlNodeList orderNodes = templateDoc.GetElementsByTagName("order"); 

XML:

<sort> 
    <order name="panelCode"> 
    <panelCode/> 
    </order> 
    <order name="panelName"> 
    <panelName/> 
    </order> 
    <order name="panelPart"> 
    <panelPart/> 
    </order> 
    <order name="numberLayers">descending 
    <numberLayers/> 
    <panelCode>ascending|ascending 
    </panelCode> 
    </order> 
</sort> 

擬似コード:これが機能する方法の例として、

foreach (orderNode) 
{ 
    if (order node title matches my string) 
    { 
    if (order node text is ascending or descending) //This check Im struggling with as I only want to check the order node text and not include any child node text in the comparison. 
    { 
     switch ascending with descending and vice versa //If i set the inner text of the order node it will effect the text contained within its child nodes. 
    } 
    else //order node text is blank 
    { 
     set ordernode text to be ascending //Again its the child nodes that could cause an issue. 
    } 
    } 
    else // order node title does not match string 
    { 
    if (order node text is ascending or descending) 
    { 
     remove order node text whilst maintaining the inner text of any child nodes. //Again its the child nodes that could cause an issue. 
    } 
    } 
} 

...

私の文字列がpanelCodeの場合は、すべての注文ノードをループします。最初は一致するので、そのオーダーノードの値を「昇順」に設定します。残りの順序ノードをループして、昇順/降順の値を持つものを探します。これは、値が ""に設定されるが、昇順|昇順などの子ノードの値を維持したいnumberLayersオーダーノードに当てはまる。したがって、解析されたドキュメントは次のようになります。

新しいXML:

<sort> 
    <order name="panelCode">ascending 
    <panelCode/> 
    </order> 
    <order name="panelName"> 
    <panelName/> 
    </order> 
    <order name="panelPart"> 
    <panelPart/> 
    </order> 
    <order name="numberLayers"> 
    <numberLayers/> 
    <panelCode>ascending|ascending 
    </panelCode> 
    </order> 
</sort> 

私が持っていた文字列は次のように提供されたXMLが判明うnumberLayersた場合:

<sort> 
    <order name="panelCode"> 
    <panelCode/> 
    </order> 
    <order name="panelName"> 
    <panelName/> 
    </order> 
    <order name="panelPart"> 
    <panelPart/> 
    </order> 
    <order name="numberLayers">ascending 
    <numberLayers/> 
    <panelCode>ascending|ascending 
    </panelCode> 
    </order> 
</sort> 
+0

私はあなたが達成する必要があるものを完全に理解していません。あなたはいくつかの文脈情報を与えることができますか? – Efrain

+0

元の回答を編集しました。 htisが助けてくれるかどうか教えてください。具体的には何が失われていますか? – user589195

+0

さて、わかりました。うーん、私は現時点ではエレガントな方法を見ていない。とにかく、私はあなたの疑似コードを実際のコードにすぐに翻訳しようとします。 ;) – Efrain

答えて

1

[OK]を、私はあなたの答えを持っていると思う:

あなたのXML構造に少し難しいのは、同じレベルにテキストノードと他のXMLノード(<panelCode/>など)があることです。それを処理するトリックは、XPath式のtext()セレクタです。ここでは、私が書くでしょう何:

string targetName = "numberLayers"; 

// grab the first matching order node 
XmlNode matchOrderNode= xmldoc.SelectSingleNode(
        "//order[@name='" + targetName + "']"); 

// try to grab the first #text leaf node, if not existing, append new 
XmlNode matchTextChildNode = matchOrderNode.SelectSingleNode("./text()"); 
if (matchTextChildNode == null) 
{ 
     matchTextChildNode = matchOrderNode.AppendChild(xmldoc.CreateTextNode(string.Empty)); 
} 

// determine whether 'ascending' is set already --> toggle 
string textToSetAfterwards = "ascending"; 
if (matchTextChildNode.Value == "ascending") 
{ 
    textToSetAfterwards = "descending"; 
} 

// clear all ascending/descending text nodes 
foreach (XmlNode orderNode in xmldoc.SelectNodes(
     "//order[text()='ascending' or text()='descending']/text()")) 
{ 
    orderNode.Value = string.Empty; 
} 

// re-set only the matched node's value 
matchTextChildNode.Value = textToSetAfterwards; 

あなたが見る、あなたが直接#テキストリーフノードを選択するXPathを使用することができます。これらの#textノードは実際には.Valueプロパティにプレーンテキストのコンテンツ(「昇順」や「降順」など)を持っています。これは読み取りと設定が可能です!

+0

よく見えます。私は/ text()xpathのものをgoogleに管理していたが、それをどのように使うべきかはわからなかった。私はこれを実装しようとし、それがどのように行くかを教えてあげます。ありがとう非常にあります:D – user589195

+0

このコードefrainに問題があります。あなたが昇順と下降を反転している場合、それはうまく動作します。しかし、新しいノードを昇順に設定したい場合は、XmlNodeのmatch = templateDoc.SelectSingleNode( "// order [@ name = '" + columnName + "']/text()[1]");ノード内にテキストが存在しないため要素を返しません。 – user589195

+0

ああ、あなたは早かったです。とにかく、私は同じことを多かれ少なかにしたと思います。 ;) – Efrain

関連する問題