【问题标题】:Unusual XML Format I Must Iterate Through我必须遍历的异常 XML 格式
【发布时间】:2017-05-06 00:37:51
【问题描述】:

我需要遍历一些格式不寻常的 XML。它看起来像这样:

<Baseball>
    <Player playerID="123" playerName="John Smith" playerBats="Right"/>    
    <position positionID="1b" positionCode="abc" counter="3"/>
    <position positionID="2b" positionCode="def" counter="2"/>
    </Player>
</Baseball>

我无法更改给我的这种格式。我需要遍历每一行,不同的部分被拉到不同的地方。我将在 C# 中编写代码。想法?谢谢!

【问题讨论】:

  • “异常格式”是否包括在position tagID = 2b 中缺少关闭&gt; 以及在名为playerplayer 中缺少早期" @987654330 @?
  • 帖子中的文本示例不代表有效的 XML - 因此,如果确实是具有代表性的示例,请停止将其称为“XML”并使用基本的文本扫描工具尝试从中提取数据。否则edit 发布更新示例并显示您尝试阅读的代码。
  • 我看不出这个 XML 有什么异常。
  • @J.N. OP 在他的 cmets 中声明,在进行“一些小的编辑”后,XmlDocument 仍然“以这种不寻常的形式”

标签: c# xml c#-5.0


【解决方案1】:

假设您输入的 XML 实际上是有效的 XML,这就是我用于此类事情的模式。

您的示例 XML 无效,因为 Player 既是自关闭的,又具有显式的关闭标记。我已经将它调整为我对它应该是什么样子的最佳猜测。

如果这确实是您必须处理的 XML,XmlDocument.LoadXml 将引发错误。您将需要找到其他方法来处理格式错误的数据,或许可以对数据进行预处理以删除 Player 元素上的 /,使其不再自动关闭。

基本模式是 XML 中的每个元素都有一个类。每个类都有一个静态函数FromXml,它接受一个XmlElement 作为XML 中的匹配元素。 FromXML 负责从属性中读取、解析和填充其属性。子元素通过在其关联类上调用 FromXml 进行处理。

    class Program
    {
        static void Main(string[] args)
        {
            string xml =
 @"<Baseball>
    <Player playerID=""123"" playerName=""John Smith"" playerBats=""Right"">    
    <position positionID=""1b"" positionCode=""abc"" counter=""3""/>
    <position positionID=""2b"" positionCode=""def"" counter=""2""/>
    </Player>
</Baseball>";

            var document = new XmlDocument();
            document.LoadXml(xml);

            var players = new List<Player>();

            foreach (XmlElement baseballElement in document.SelectNodes("Baseball"))
            {
                foreach (XmlElement playerElement in baseballElement.SelectNodes("Player"))
                {
                    players.Add(Player.FromXml(playerElement));
                }
            }
            Console.ReadLine();
        }
    }

    public class Player
    {
        public static Player FromXml(XmlElement PlayerElement)
        {
            var player = new Player();
            player.PlayerId = int.Parse(PlayerElement.GetAttribute("playerID"));
            player.PlayerName = PlayerElement.GetAttribute("playerName");
            player.PlayerBats = PlayerElement.GetAttribute("playerBats");

            foreach (XmlElement positionElement in PlayerElement.SelectNodes("position"))
            {
                player.Positions.Add(Position.FromXml(positionElement));
            }
            return player;
        }

        public int PlayerId { get; set; }

        public string PlayerName { get; set; }

        public string PlayerBats { get; set; }

        private List<Position> _positions = new List<Position>();
        public List<Position> Positions
        {
            get { return _positions; }
        }
    }

    public class Position
    {
        public static Position FromXml(XmlElement positionElement)
        {
            var position = new Position();
            position.PositionId = positionElement.GetAttribute("positionID");
            position.PositionCode = positionElement.GetAttribute("positionCode");
            position.Counter = int.Parse(positionElement.GetAttribute("counter"));

            return position;
        }

        public string PositionId { get; set; }
        public string PositionCode { get; set; }
        public int Counter { get; set; }
    }

这将创建一个 Player 列表,每个列表都包含一个 Position 列表,全部由 XML 填充。

我也没有对输入 XML 进行任何类型的错误检查。如果缺少任何属性或格式错误,则会引发错误。

【讨论】:

  • 看到您的回复我非常兴奋。当我第一次开始阅读代码时,有一行很突出,结果我的 IDE 也不太关心它。它是: public List Positions { get; } = 新列表();您如何将其拆分为 C# 5?谢谢!
  • 将该属性更改为带有支持字段的“普通”只读属性,并在构造函数中初始化该字段(您还必须添加该字段)。我现在在手机上,所以我无法更新代码。如果您希望我在使用计算机后对其进行更新,请告诉我。
  • 请做。我已经重读了你刚刚写的 5 遍,我还在尝试解析它。
  • 代码已更新。我最终使用了字段初始化程序而不是构造函数,使其更接近我的原始代码。
  • 抱歉耽搁了,结果孩子生病了。这非常适合我需要它做的事情。谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-02-24
  • 2015-09-15
  • 2011-12-25
  • 1970-01-01
  • 2020-05-29
  • 2014-07-12
  • 1970-01-01
  • 2010-12-27
相关资源
最近更新 更多