3

3部構成の質問。

親の他の子を取得するために、その中の子によって特定のXMLノードを見つけることは可能ですか?例:

<House>
    <Kitchen>
        <Appliance>
            <Name>Refrigerator</Name>
            <Brand>Maytag</Brand>
            <Model>F2039-39</Model>
        </Appliance>
        <Appliance>
            <Name>Toaster</Name>
            <Brand>Black and Decker</Brand>
            <Model>B8d-k30</Model>
        </Appliance>
    </Kitchen>
</House>

そのため、「冷蔵庫」または「トースター」を検索して適切なアプライアンスノードを見つけ、そこからブランドを取得したいと思います。

この質問の2番目の部分はこれです:これはそれを行うための愚かな方法ですか?Applianceタグで属性を使用すると、これがはるかに簡単になりますか?もしそうなら、どのように私はそれをそのように見つけるでしょうか?

3番目の部分については、アプライアンスを見つけたら、その特定のアプライアンスのモデルなどをどのように変更しますか?

4

4 に答える 4

3

XLinqを使用すると、このクエリをかなり自然に実行できます。

// Given:
//   var xdoc = XDocument.Load(...);
//   string applianceName = "Toaster";

// Find the appliance node who has a sub-element <Name> matching the appliance
var app = xdoc.Root
              .Descendants("Appliance")
              .SingleOrDefault(e => (string)e.Element("Name") == applianceName);

// If we've found one and it matches, make a change
if (app != null)
{
    if (((string)app.Element("Model")).StartsWith("B8d-k30"))
    {
        app.Element("Model").Value = "B8d-k30 Mark II";
    }
}

xdoc.Save(@"output.xml"); // save changes back to the document
于 2012-07-06T16:56:13.543 に答える
3

XmlDocumentを使用している場合

foreach(XmlNode applianceNode in 
          myDocument.DocumentElement.SelectNodes("Kitchen/Applicance[Name='Refrigerator']")
{
   XmlNode modelNode = applicianceNode.SelectSingleNode("Model").InnerText = SomeOtherValue;
}

名前タグを属性(applicanceName)にした場合、これにはほとんど違いがありません。

foreach(XmlNode applianceNode in 
          myDocument.DocumentElement.SelectNodes("Kitchen/Applicance[@applianceName='Refrigerator']")
{
// ...
}
于 2012-07-06T17:05:39.183 に答える
0
    string xml = @"<House>
    <Kitchen>
        <Appliance>
            <Name>Refrigerator</Name>
            <Brand>Maytag</Brand>
            <Model>F2039-39</Model>
        </Appliance>
        <Appliance>
            <Name>Toaster</Name>
            <Brand>Black and Decker</Brand>
            <Model>B8d-k30</Model>
        </Appliance>
    </Kitchen>
</House>";

    XDocument xdoc = XDocument.Parse(xml);

    string newModel = "B8d-k45";

    var matchingElement = (from appliance in xdoc.Descendants("Appliance")
                           where appliance.Element("Name").Value == "Toaster"
                           select appliance).FirstOrDefault();

    if (matchingElement != null)
    {
        matchingElement.Element("Model").Value = newModel;
    }

    Console.WriteLine(xdoc.ToString());
于 2012-07-06T17:53:18.523 に答える
0

ネクロマンシング。
はい、XPathを使用するとさらに簡単になり、Linqがなくても完全に機能し
ます。..を使用して親ノードにアクセスするだけです(2番目の考えでは、「ordinalignorecase」を使用するとLinqの方が簡単になります)

public static void CreateNewHouse()
{
    System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
    doc.XmlResolver = null;
    doc.Load(@"d:\House.xml");

    foreach (System.Xml.XmlNode modelNode in doc.DocumentElement
.SelectNodes("/House/Kitchen/Appliance/Name[text()='Refrigerator']/../Model"))
    {
        modelNode.InnerText = "A New Value";
    }

    doc.Save(@"d:\MyHouse.xml");
}

MyHouse.xml:

<House>
  <Kitchen>
    <Appliance>
      <Name>Refrigerator</Name>
      <Brand>Maytag</Brand>
      <Model>A New Value</Model>
    </Appliance>
    <Appliance>
      <Name>Toaster</Name>
      <Brand>Black and Decker</Brand>
      <Model>B8d-k30</Model>
    </Appliance>
  </Kitchen>
</House>

大文字と小文字を区別しない必要がある場合は、text()を次のように置き換えます。

translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')

(ASCII /英語のみ)そしてもちろん「冷蔵庫」を小文字に変更します(「冷蔵庫」)

XMLドキュメントにデフォルトの名前空間がある場合は、Select*Nodeで指定する必要があります。

 xnImageTag.SelectSingleNode("./dft:Source", nsmgr);

どこ

System.Xml.XmlNamespaceManager nsmgr = GetReportNamespaceManager(doc);

public static System.Xml.XmlNamespaceManager GetReportNamespaceManager(System.Xml.XmlDocument doc)
{
    if (doc == null)
        throw new ArgumentNullException("doc");

    System.Xml.XmlNamespaceManager nsmgr = new System.Xml.XmlNamespaceManager(doc.NameTable);

    // <Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">

    if (doc.DocumentElement != null)
    {
        string strNamespace = doc.DocumentElement.NamespaceURI;
        System.Console.WriteLine(strNamespace);
        nsmgr.AddNamespace("dft", strNamespace);
        return nsmgr;
    }

    nsmgr.AddNamespace("dft", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
    // nsmgr.AddNamespace("dft", "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition");

    return nsmgr;
} // End Function GetReportNamespaceManager
于 2015-03-25T15:05:02.607 に答える