如何在没有名称的XML中查找属性及其值?

时间:2018-04-03 10:32:21

标签: c# xml

我是C#

的新手

这里是xml:

<ROOT>
  <Columns BaseXPath="//Orders/Position/">
    <Colum XPath="@PositionSK" Name="Position"/>
    <Colum XPath="@PosGroup" Name="Gruppen-Nr"/>
    <Colum XPath="@PosNumber" Name="PositionsNr"/>
    <Colum XPath="@PositionCommercialTypeSK" Name="Status"/>
    <Colum XPath="@BundlePositionSK" Name="BundlePositionSK"/>
    <Colum XPath="@MainPositionSK" Name="MainPositionSK"/>
    <Colum XPath="@SalesAgentPrice" Name="Preis"/>
    <Colum XPath="@BookingUnitSK" Name="Buch"/>
    <Colum XPath="@ContentComponentCommSK" Name="IKO"/>
    <Colum XPath="@PositionTypeSK" Name="PositionsTyp"/>
    <Colum XPath="//Advertisement[@AdvertisementSK = PositionAdvertisementRelationship/@AdvertisementSK]/@AdvertisementSK" Name="AdvertisementSK"/>
    <Colum XPath="//Advertisement[@AdvertisementSK = PositionAdvertisementRelationship/@AdvertisementSK]/@AdvertisementTypeSK" Name="Formatvorgabe"/>
  </Columns>
</ROOT>

此xml可以随时更改。所以它永远不变。有时会有更多的信息,有时甚至更少。

这个xml给我一些信息,应该在第二个“主xml”中搜索。

所以现在我知道我必须找到PositionSK,PosGroup,PositionCommercialTypeSK,......的属性。在另一个xml。

但我怎么能这样做?名字永远不变,所以我需要一个占位符吗?

我试过了:

public class ResultNames
{
    XmlDocument xml = new XmlDocument();

    public List<ResultNames> GetRightNames (string file)
    {
        xml.Load(file); //this is the xml file

        var list = xml.SelectNodes("//ROOT/Columns/Colum");

        foreach ( XmlNode colum in list)
        {
            XmlNode bla = colum.Attributes; //I dont know what I can do here, without any name.
        }

        return null;
    }

和其他xml文件一样,我需要一个额外的类吗?

来自其他xml的小样本:

<Set>
  <Orders OrderSK="0013233309" OrderTypeSK="ORDER" OrderDate="2000-01-01T12:00:00" OrderPrice="0.0000" OrderQuantity="0.00" DistrictSK="0026070180" PaymentTypeSK="E" OrderCreationTypeSK="SNW5ORD" SalesAgentSK="0020025518" ChangeDate="2018-01-25T15:48:29" SalesOrganisationSK="K10-100-1000-50-65" ChangeDateFS="2017-12-11T15:25:21" Source="CORE" Status="C">
    <Position PosNumber="3" PosGroup="5" PositionTypeSK="ONL" PositionCommercialTypeSK="DEFAULT"

但是它要大得多。

2 个答案:

答案 0 :(得分:1)

使用Xml Linq和字典

04-03 12:37:20.714 5819-6352:  Removed from folder /storage/emulated/0/Pictures/GR --> File name ic_alarm_white_24dp.png
04-03 12:37:20.714 5819-6352:  Does not Exists
04-03 12:37:20.714 5819-6352:  is  NOT Directory
04-03 12:37:20.714 5819-6352:  is  NOT File

下面的代码只从第一个Xml文件中获取名称

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME1 = @"c:\temp\test.xml";
        const string FILENAME2 = @"c:\temp\test1.xml";
        static void Main(string[] args)
        {

            XDocument doc = XDocument.Load(FILENAME1);

            Dictionary<string, XElement> dict = doc.Descendants("Columns").FirstOrDefault().Elements()
                .GroupBy(x => (string)x.Attribute("XPath"), y => y)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());

            XDocument order = XDocument.Load(FILENAME2);
            List<XElement> positions = order.Descendants("Position").ToList();

            foreach (XElement position in positions)
            {
                foreach (XAttribute attribute in position.Attributes())
                {
                    string name = attribute.Name.LocalName;
                    string value = (string)attribute;

                    XElement element = dict["@" + name];
                    element.SetValue(value);


                }
            }



        }
    }

}

答案 1 :(得分:1)

我必须对您正在使用的数据做出一些假设,因为您没有提供所有内容的示例。

第一个假设是第二个XML文档的格式。我不得不从第一份文件的格式中猜出来。

第二个假设是第一个文档Colum元素中指定的XPATH始终指向Attribute

void Main()
{
    string xml1 =
@"<ROOT>
  <Columns BaseXPath=""//Orders/Position/"">
    <Colum XPath=""@PositionSK"" Name=""Position""/>
    <Colum XPath=""@PosGroup"" Name=""Gruppen-Nr""/>
  </Columns>
</ROOT>";

    string data =
@"<Set>
    <Orders>
        <Position PositionSK=""A"" PosGroup=""1"" SomeOtherAttribute=""ABC"" />
        <Position PositionSK=""B"" PosGroup=""2"" SomeOtherAttribute=""DEF"" />
    </Orders>
</Set>";

    var schemaDoc = XDocument.Parse(xml1);
    var dataDoc = XDocument.Parse(data);

    var itemsXPath = schemaDoc.Descendants("Columns").FirstOrDefault()?.Attribute("BaseXPath").Value;

    var basePath = schemaDoc.Descendants("Columns").FirstOrDefault().Attribute("BaseXPath").Value;
    // XPATH isn't supposed to end with a trailing "/".
    if (basePath.EndsWith("/"))
    {
        basePath = basePath.Substring(0, basePath.Length - 1);
    }
    var lines = dataDoc.XPathSelectElements(basePath);

    var rowIndex = 0;
    foreach (var line in lines)
    {
        Console.WriteLine($"---Row {rowIndex}");
        foreach (var col in schemaDoc.Descendants("Colum"))
        {
            var columnName = col.Attribute("Name").Value;
            Console.Write($"{columnName}: ");

            var columnValue = ((XAttribute)((IEnumerable<Object>)line.XPathEvaluate(col.Attribute("XPath").Value)).FirstOrDefault()).Value;
            Console.WriteLine(columnValue);
        }

        Console.WriteLine();
        rowIndex++;
    }
}

这会产生以下输出:

  

---第0行   职位:A
  Gruppen-Nr:1

     

---第1行   职位:B
  Gruppen-Nr:2

您可以通过调整xml1的内容来更改输出的属性。