在xml中使用其属性查找特定节点时遇到问题

时间:2016-04-22 07:00:46

标签: c# .net xml winforms attributes

我有以下XML文件,想要查找具有特定属性的元素。我想找到的是"Type" == "Billing"寻找属性。

<?xml version="1.0"?>
<PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20">
  <Address Type="Shipping">
    <Name>Ellen Adams</Name>
    <Street>123 Maple Street</Street>
    <City>Mill Valley</City>
    <State>CA</State>
    <Zip>10999</Zip>
    <Country>USA</Country>
  </Address>
  <Address Type="Billing">
    <Name>Tai Yee</Name>
    <Street>8 Oak Avenue</Street>
    <City>Old Town</City>
    <State>PA</State>
    <Zip>95819</Zip>
    <Country>USA</Country>
    <Address Type="Shipping">
        <Name>Ellen Adams</Name>
    </Address>
    <Address Type="transporting">
        <Name>Tai Yee</Name>
        <Street>8 Oak Avenue</Street>
    </Address>
  </Address>
</PurchaseOrder>

问题在于,第二个Address节点有一些其他内部节点与我真正想拥有的内容无关。我的意思是Shippingtransporting的属性不应该在输出中。如果我认为只有以下输出需要什么代码?

<Address Type="Billing">
  <Name>Tai Yee</Name>
  <Street>8 Oak Avenue</Street>
  <City>Old Town</City>
  <State>PA</State>
  <Zip>95819</Zip>
  <Country>USA</Country>
</Address>

我的代码是:

XElement root = XElement.Load("PurchaseOrder.xml");
IEnumerable<XElement> address =
    from el in root.Elements("Address")
    where (string)el.Attribute("Type") == "Billing"
    select el;
foreach (XElement el in address)
    Console.WriteLine(el);

2 个答案:

答案 0 :(得分:1)

开始和结束标记之间的所有内容都是元素的一部分。要获得所需的输出,您需要1.重建元素以仅包含所需的信息:

foreach (XElement el in address)
{
    var newElement = new XElement(
                            el.Name.LocalName,
                            el.Attributes(),
                            el.Elements().Where(o => o.Name.LocalName != "Address")
                     );
    Console.WriteLine(newElement.ToString());
}

或2.删除所有不必要的信息,即Address元素:

foreach (XElement el in address)
{
    el.Elements("Address").Remove();
    Console.WriteLine(el.ToString());
}

答案 1 :(得分:0)

我将如何做到这一点

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

namespace ConsoleApplication87
{
    namespace Linq
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                List<string> acceptableElements = new List<string>(){"Name", "Street", "City", "State", "Zip", "Country"};

                XDocument doc = XDocument.Load(FILENAME);
                List<XElement> addresses = doc.Descendants("Address").ToList();
                XElement billing = addresses.Where(x => x.Attribute("Type").Value == "Billing").FirstOrDefault();
                addresses.Remove();
                XElement po = (XElement)doc.FirstNode;
                po.Add(billing);
            }
        }
    }


}