C#将未知的XML字符串转换为树

时间:2017-10-02 18:51:00

标签: c# asp.net .net xml asp.net-mvc

我正在尝试将XML文件(我不知道的内容/结构)转换为自定义树。 该树具有以下形式的构造函数:

InformationNode(字符串键,字符串值,'枚举'类型)

InformationNode有一个 addChild 函数,没有子项数量的限制。我目前的代码如下:

public static InformationNode fromXML(String xml)
    {
        xml = xml.Replace("< ", "<").Replace("</ ", "</"); //Bugfix for some API's.
        XDocument xdoc = XDocument.Parse(xml);
        var details = xdoc.Root.Elements();
        String key = "->";

        InformationNode node = new InformationNode(key, "", InformationType.Object);
        foreach (var detail in details)
        {
            //If XML is Leaf.
            if (details.Count() == 0 && int.TryParse(detail.Value.Trim().ToString(), out var n))
                 return new InformationNode(key, detail.Value.Trim().ToString(), InformationType.Int);
            if (details.Count() == 0)
                 return new InformationNode(key, detail.Value.Trim().ToString(), InformationType.String);
            //If XML is object:
            node.addChild(fromXML(detail.Value.Trim()));                
        }
        return node;
    }

但遗憾的是返回了一个空节点。 谁能告诉我我做错了什么?

编辑: 根据要求:2个测试用例。

InformationNode a = InformationNode.fromXML("<stationcode> 6391 </ stationcode >"); 
InformationNode b =  InformationNode.fromXML("<?xml version=\"1.0\" encoding=\"utf - 8\" ?><weerstation id=\"6391\"><stationcode> 6391 </ stationcode >< stationnaam regio = \"Venlo\" > Meetstation Arcen </ stationnaam >< lat > 51.50 </ lat >< lon > 6.20 </ lon >< datum > 09 / 28 / 2017 20:20:00 </ datum >< luchtvochtigheid > 80 </ luchtvochtigheid >< temperatuurGC > 18.7 </ temperatuurGC >< windsnelheidMS > 3.5 </ windsnelheidMS >< windsnelheidBF > 3 </ windsnelheidBF >< windrichtingGR > 207 </ windrichtingGR >< windrichting > ZZW </ windrichting >< luchtdruk > -</ luchtdruk >< zichtmeters > -</ zichtmeters >< windstotenMS > 6.4 </ windstotenMS >< regenMMPU > -</ regenMMPU >< zonintensiteitWM2 > -</ zonintensiteitWM2 >< icoonactueel ID = \"cc\" zin = \"Zwaar bewolkt\" >https://www.buienradar.nl/resources/images/icons/weather/30x30/cc.png</ icoonactueel >< temperatuur10cm > 18.2 </ temperatuur10cm >< url >http://www.buienradar.nl/nederland/weerbericht/weergrafieken/6391</ url >< latGraden > 51.83 </ latGraden >< lonGraden > 6.33 </ lonGraden ></ weerstation > ");

1 个答案:

答案 0 :(得分:0)

根据你想要做的事情,我认为这就是你所追求的:

public static InformationNode fromXML(String xml)
{
    xml = xml.Replace("< ", "<").Replace("</ ", "</"); //Bugfix for some API's.
    var xdoc = XDocument.Parse(xml);
    var details = xdoc.Root.Elements();
    var key = "->";

    var node = new InformationNode(key, "", InformationType.Object);

    // Do we have any child nodes?
    if(details != null && details.Any())
    {
        foreach (var detail in details)
        {
            //If XML is object, recurse:
            node.addChild(fromXML(detail.ToString()));                
        }
    }
    else
    {
        // No child nodes - try to read the current element's value
        var rootValue = xdoc.Root.Value.Trim();

        //If XML is Leaf.
        if (int.TryParse(rootValue, out var n))
        {
            node = InformationNode(key, rootValue, InformationType.Int);
        }
        else
        {
            node = InformationNode(key, rootValue, InformationType.String);
        }
    }

    return node;
}

XDocument.RootXElement,因此如果它没有子元素,您只需读取它的值即可。您可能想要添加对空字符串或空字符串的检查。

如果可能的话,我也更喜欢在给定的方法中只有一个退出点,所以我稍微更新了解析部分。

除非您计划提供InformationNode等的实施,否则这是未经测试的。