从整个XDocument中提取属性

时间:2017-11-18 20:04:52

标签: c# xml linq xml-parsing

以下XDocument包含存储在XElement成员中的(x,y)坐标,这些坐标在属性' x',' y',' x1',& #39; y1',' z'和' z1':

<?xml version="1.0" encoding="utf-8"?>
<shapes>
  <shape>
    <connections />
    <foreground>
      <strokewidth width="0.1" />
      <path>
        <move x="1395.6" y="84.6" />
        <line x="80.1" y="84.6" />
        <curve x1="75.1" y1="84.6" x2="71.1" y2="88.6" x3="71.1" y3="93.6" />
        <line x="71.1" y="402.6" />
        <close />
      </path>
      <fillstroke />
    </foreground>
  </shape>
</shapes>

最简单的推荐方法是仅提取属性的值&#39; x&#39;从整个文档中不循环遍历所有元素并检查特定属性?给定XML理想情况下会产生&#39; x&#39;坐标:

float[] x= {1395.6, 80.1, 71.1};
float[] x1 = {75.1};

同样的&#39; y&#39;,&#39; y1&#39;,...

编辑: 由于坐标始终位于&#39; leaf&#39; xml元素,我最终使用了:

return fileXml.Root.Descendants()
                .Where(e => e.HasElements == false) // leaf element
                .Where(e => e.Attribute("x") != null)
                .Select(c => c.Attribute("x").Value).Select(float.Parse)
                .ToList(); // or .ToArray();

它也可以包含在辅助函数中。

2 个答案:

答案 0 :(得分:2)

您可以使用xpath。 XPath表达式fields_for将匹配名称为//@x的所有属性:

x

答案 1 :(得分:1)

有些人可能喜欢这种解决方案而其他人可能不喜欢。它有点复杂,但使用xml linq

将整个xml解析为x,y对
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 FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            List<KeyValuePair<string, List<KeyValuePair<double, double>>>> instructions = new List<KeyValuePair<string, List<KeyValuePair<double, double>>>>();

            foreach (XElement instruction in doc.Descendants("path").FirstOrDefault().Elements())
            {
                List<KeyValuePair<double, double>> points = new List<KeyValuePair<double, double>>();
                for (int i = 0; i < instruction.Attributes().Count(); i += 2)
                {
                    points.Add(new KeyValuePair<double,double>((double)instruction.Attributes().Skip(i).FirstOrDefault(), (double)instruction.Attributes().Skip(i + 1).FirstOrDefault()));
                }
                instructions.Add(new KeyValuePair<string, List<KeyValuePair<double,double>>>( instruction.Name.LocalName, points));
            }

        }
    }
}
相关问题