使用Linq更改XML结构并遇到foreach问题

时间:2015-04-24 14:47:12

标签: c# linq

我一直致力于一个家庭项目,将我当前CMS(Orchard CMS)中导出的XML文件转换为新的结构(BlogML),以便我可以将其导入到Umbraco。

到目前为止,我已经使用Linq来强化新的XML结构,它是一个属性和元素的空壳,但是我对于更精细的点有一些问题。

Orchard CMS XML的摘录是:

  <BlogPost Id="/alias=The Blog\/2012\/09\/10\/on-starters-orders" Status="Published">
  <TextField.Excerpt />
  <TaxonomyField.Categories Terms="" />
  <TaxonomyField.Tags Terms="" />
  <BodyPart Text="&lt;p&gt;&#xD;&#xA;&#x9;Well, this is the first blog I have setup which will be something I will try and keep updated as much as possible.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;There are two reasons for the blog, well, two that I can think of just now. The first is to allow me to use my ASP.net programming skills on a more regular basis, not just for work. The second is to post my daily, weekly, monthly progress on my mission to get a qualifying time for Glasgow Commonwealth Games in 2014!&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;You can have a look at my bio to find out more about me but what you wont find in there is what made me decide to give this huge challange a go.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;Hopefully over the coming blogs I can share with you all my thoughts, my high and low moments and maybe in a round about sort of way, give something back to everyone who has given me support.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;I&amp;#39;ve been running since 2008 when I was 18.5 stone (257lbs) and I needed to loose weight, since then I have found that I am actually not that bad at this running thing! In 2008 after I had ran Edinburgh Marathon and raised money for the RNLI,&amp;nbsp;I visited my local running club, Pitreavie AAC, and was welcomed with&amp;nbsp;open arms but was told that I may struggle for the longer distances as my pace was a bit slower than the others. This was my first challange, become faster and not the last one home on a Tuesday or Thursday evening.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;Over time I started to progress through the groups, always pushing and always aiming for the top group, the really fast guys and girls. It took me a while but eventually I got there and in the process became the Team Manager for the Pitreavie AAC Road Runners, a role which I have had for the past 2 years.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;My pace is much quicker than when I first joined the club but on a national level, I still have some way to go! After the Olympic games it got me thinking, what would it take to get to an Olympics, then I scaled by dreams down a bit, for a bit anyway, then I thought, what would it take to get in to the Commonwealth Games. After a quick search on the interweb I found the qualifying time for the marathon distance for the Scottish Athletics. 2:19:00, two hours and nineteen minutes, that exquates to 5 minutes 18seconds a mile!&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;At this point you would expect someone to go, that&amp;#39;s crazy pace, I will never manage that, but then you haven&amp;#39;t met me or if you have, you will know what I said next.....I can do that!&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;After a chat with my fiancee, a number of emails and phone calls were made, first to find a coach, then&amp;nbsp;to find someone to give me nutritional advice and then a physio. The rest is history, I am now training to get a qualifying time for the Commonwealth Games!&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;&amp;nbsp;&lt;/p&gt;&#xD;&#xA;" />
  <CommonPart Owner="/User.UserName=Owain" Container="/alias=blog" CreatedUtc="2012-09-10T13:27:00Z" PublishedUtc="2012-09-25T08:57:25Z" ModifiedUtc="2012-09-25T08:56:15Z" />
  <AutoroutePart Alias="The Blog/2012/09/10/on-starters-orders" UseCustomPattern="false" />
  <TitlePart Title="On starters orders....." />
  <CommentsPart CommentsShown="true" CommentsActive="true" ThreadedComments="false" />
  <TagsPart Tags="" />
</BlogPost>
<BlogPost Id="/alias=The Blog\/2012\/09\/09\/first-race-on-a-track" Status="Published">
  <TextField.Excerpt />
  <TaxonomyField.Categories Terms="" />
  <TaxonomyField.Tags Terms="" />
  <BodyPart Text="&lt;p&gt;&#xD;&#xA;&#x9;Coach wanted to see what I can do just now, one mile on the track, nothing more, nothing less. There was a local meet at Pitreavie AAC and there just so happened to be a one mile race scheduled. Here was my chance to see what I could do.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;I went for a warm up about 20mins before the race and then waited, waited a bit more and by the time the race was called to start, I had cooled down again! Not great but no excuses. On your marks, and then bang! off went the gun. I started off well but I was tense, nervous and not running fluid. It was strange running round a track where people can see every move you make, every stride and every breath you make! Round and round, watching. I was quite comfortably in last place with no hope of catching my club mate which is probably the fastest road runner the club has and he was even trailing from the front runners - these guys were quick!&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;I finished in 5:24.09 which isnt too bad! I expected worse and that is after a tough session on Thursday.&amp;nbsp;12 x 400m with 100m recovery between each rep.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;After the race I ran back home (18miles) and it hurt! It was really windy over the Forth Road Bridge, the pace wasn&amp;#39;t too bad considering but the last 2 miles of the run home were the worst, I think I was dehydrated more than anything.&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&#xD;&#xA;&#x9;Will have a rest day tomorrow, apart from BodyPump class, and then get to club on Tuesday.&lt;/p&gt;&#xD;&#xA;" />
  <CommonPart Owner="/User.UserName=Owain" Container="/alias=blog" CreatedUtc="2012-09-09T13:00:00Z" PublishedUtc="2012-09-25T08:56:53Z" ModifiedUtc="2012-09-25T08:56:53Z" />
  <AutoroutePart Alias="The Blog/2012/09/09/first-race-on-a-track" UseCustomPattern="false" />
  <TitlePart Title="First race on a track" />
  <CommentsPart CommentsShown="true" CommentsActive="true" ThreadedComments="false" />
  <TagsPart Tags="" />
 </BlogPost>

我需要做的是将一些信息输入

 <posts>
<post id="" date-created="" date-modified="" approved="true" post-url="" type="normal" hasexcerpt="false" views="" is-published="true">
  <title type="text"><![CDATA[]]></title>
  <content type="text"><![CDATA[]]]></content>
  <post-name type="text"><![CDATA[]]></post-name>
  <authors>
    <author ref="Owain" />
  </authors>
  <categories>
    <category ref="1" />
  </categories>
  <tags>
    <tag ref="" />
  </tags>
</post>

并循环遍历原始XML文件,以从 CommonPart CreatedUTC 填充 Date-created ,从 BodyPart Text <填充 Content / em>等基本上我认为一旦我能得到一些信息,我应该能够弄清楚如何做其余的事情。

到目前为止,我已对此进行了编码:

  protected void btnBuild_Click(object sender, EventArgs e)
    {
        XElement xe = XElement.Load(Server.MapPath("test.xml"));

        XName blogPost = XName.Get("BlogPost");
        XName bodyPart = XName.Get("BodyPart");



        //foreach (var bodyPartElement in xe.Elements(blogPost))
        //{
        //    var locElement = bodyPartElement.Element(bodyPart);
        //    string textElement = locElement.LastAttribute.ToString();
        //    string newText = textElement.Remove(0, 7);

        //    System.Diagnostics.Debug.WriteLine(newText);

        //}

        XElement contacts =
            new XElement("blog",
                new XAttribute("root-url", "testing"),
                new XAttribute("date-created", DateTime.Now.ToString()),


                new XElement("title",
                    new XAttribute("type", "text"),
                    new XCData("BlogML 2.0 Sample Blog")
                ),

                new XElement("sub-title",
                        new XAttribute("type", "text"),
                        new XCData("This is a sample blog content for BlogML 2.0")

                    ),

                new XElement("authors",
                    new XElement("author",
                        new XAttribute("id", "2100"),
                        new XAttribute("date-created", DateTime.Now.ToString()),
                        new XAttribute("date-modified", DateTime.Now.ToString()),
                        new XAttribute("approved", "true"),
                        new XAttribute("email", "owaingdwilliams@gmail.com"),

                        new XElement("title",
                            new XAttribute("type", "text"),
                            new XCData("Owain")
                            )
                        )
                        ),

                        new XElement("extended-properties",
                    new XElement("property",
                        new XAttribute("name", "CommentModeration"),
                        new XAttribute("value", "anonymous")
                        ),

                        new XElement("property",
                            new XAttribute("name", "SendTrackback"),
                            new XAttribute("value", "true")

                        )),

                        new XElement("categories",
                    new XElement("category",
                        new XAttribute("id", "1"),
                        new XAttribute("date-created", System.DateTime.Now.ToString()),
                        new XAttribute("date-modified", System.DateTime.Now.ToString()),
                        new XAttribute("approved", "true"),
                        new XAttribute("parentref", ""),

                        new XElement("title",
                            new XAttribute("type", "text"),
                            new XCData("Owain's Blog")

                        )
                        ),

                        new XElement("category",
                        new XAttribute("id", "2"),
                        new XAttribute("date-created", System.DateTime.Now.ToString()),
                        new XAttribute("date-modified", System.DateTime.Now.ToString()),
                        new XAttribute("approved", "true"),
                        new XAttribute("parentref", ""),

                        new XElement("title",
                            new XAttribute("type", "text"),
                            new XCData("Mandy's Blog")

                        )
                        )),


                        //Blog Post Section
                        //TODO create a loop to parse each post. 

                        new XElement("posts",
                            new XElement("post",
                                new XAttribute("id", ""),
                                new XAttribute("date-created",""),
                                new XAttribute("date-modified", ""),
                                new XAttribute("approved","true"),
                                new XAttribute("post-url",""),
                                new XAttribute("type","normal"),
                                new XAttribute("hasexcerpt","false"),
                                new XAttribute("views",""),
                                new XAttribute("is-published","true"),
                                new XElement("title",
                                    new XAttribute("type","text"),
                                    new XCData("")),


                                    new XElement("content",
                                    new XAttribute("type","text"),
                                    new XCData("")                                                                                
                                    ),



                                new XElement("post-name",
                                    new XAttribute("type","text"),
                                    new XCData("")),
                                new XElement("authors",
                                    new XElement("author",
                                        new XAttribute("ref","Owain")
                                )),
                                new XElement("categories",
                                    new XElement("category",
                                        new XAttribute("ref","1"))
                                    ),
                                    new XElement("tags",
                                        new XElement("tag",
                                            new XAttribute("ref",""))
                                        )


                                    )));
        contacts.Save(Server.MapPath("Build.xml"));

希望那里有帮助。 感谢。

更新

我已经走下了序列化路线,但现在收到错误在XML中的 的Xml文档中存在错误( 文件。

我的代码来自MSDN示例:

protected void btnSerialization_Click(object sender, EventArgs e)
    {
        string path = Server.MapPath("export.xml");
        XmlRootAttribute xRoot = new XmlRootAttribute();
        xRoot.ElementName = "Data";
        xRoot.IsNullable = true;

        // Create an instance of the XmlSerializer specifying type and namespace.
        XmlSerializer ser = new XmlSerializer(typeof(Data), xRoot);
        ser.UnknownNode += new
        XmlNodeEventHandler(ser_UnknownNode);
        ser.UnknownAttribute += new
        XmlAttributeEventHandler(ser_UnknownAttribute);




        // A FileStream is needed to read the XML document.
        FileStream fs = new FileStream(path, FileMode.Open);
        XmlReader reader = XmlReader.Create(fs);

        Data bl;


        // Declare an object variable of the type to be deserialized.
        bl = (Data)ser.Deserialize(fs);

        lblInfo.Text = bl.BlogPost.ToString();

        fs.Close();



    }

    private void ser_UnknownNode (object sender, XmlNodeEventArgs e)
    {
        lblInfo.Text = "Unknown Node"+e.Name+"\t"+e.Text;
    }
    private void ser_UnknownAttribute(object sender, XmlAttributeEventArgs e)
    {
        System.Xml.XmlAttribute attr = e.Attr;
        lblInfo.Text = "Unknown Att" + attr.Name + "\t" + attr.Value;
    }

电子邮件文件的路径似乎很好,因为它找到了XML文件,我使用了xsd.exe文件来创建.cs并使用Visual Studio来创建XML文件的模式。 我觉得我只是想知道如何解决这个问题。

更新2

          string path = Server.MapPath("export.xml");
        XmlRootAttribute xRoot = new XmlRootAttribute();
        xRoot.ElementName = "Data";
        xRoot.IsNullable = true;


        Data myObject = new Data();
        XmlSerializer ser = new XmlSerializer(myObject.GetType(),xRoot);
        using (FileStream fs = new FileStream(path, FileMode.Open))
        {
            XmlTextReader reader = new XmlTextReader(fs);
            myObject = (Data)ser.Deserialize(reader);
            lblInfo.Text = myObject.BlogPost[1].BodyPart.Text;
        }

现在读取XML文件并显示第一个博客的第一个bodyPart!差不多了!谢谢您的帮助。

2 个答案:

答案 0 :(得分:2)

所有这些代码都过于复杂。我建议您使用xml序列化从xml导入数据,通过c#类操作数据并以xml格式输出。有关更多信息,请参阅此post

更新有关实现方法的更多详细信息:

MyClass myObject = new MyClass;
XmlSerializer ser = new XmlSerializer(myObject.GetType());
using (FileStream fs = new FileStream(FilePath, FileMode.Open))
{
    XmlTextReader reader = new XmlTextReader(fs);
    myObject = (MyClass)ser.Deserialize(reader);
}

答案 1 :(得分:0)

这个怎么样:

//Blog Post Section
//TODO create a loop to parse each post. 

new XElement("posts",
    xe
    .Elements("BlogPost")
    .Select(x => 
        new XElement("post",
            new XAttribute("date-created", x.Element("CommonPart").Attribute("CreatedUtc").Value),
            new XElement("content",
                new XAttribute("type","text"),
                new XCData(x.Element("BodyPart").Attribute("Text").Value)))));

这个例子只映射了几个字段(我不知道应该如何映射其余字段),但我认为它应该让你朝着正确的方向前进。哦,我添加了create a loop to parse each post注释,以指示您的示例中您将实现此目的,而不是暗示我们正在使用循环来解决此问题。