使用过滤器将Linq上的CDATA内部值提取到XML

时间:2012-01-24 16:34:42

标签: c# xml linq

我正在使用此代码从XML中检索我想要的值:

IEnumerable<ForewordReview> reviews = null;
try
{
    reviews = from item in xmlDoc.Descendants("node")
              select new ForewordReview()
              {
                  PubDate = item.Element("created").ToString(),
                  Isbn = item.Element("isbn").ToString(),
                  Summary = item.Element("review").ToString()
              };
} // ...

顺便提一下,客户现在几乎每个带有CDATA的标签都会传递给我们:

<review>
    <node>
        <created>
            <![CDATA[2012-01-23 12:40:57]]>
        </created>
        <isbn>
            <![CDATA[123456789]]>
        </isbn>
        <summary>
            <![CDATA[Teh Kittehs like to play in teh mud]]>
        </summary>
    </node>
</review>

我已经看到了一些从CDATA标记中提取这些值的解决方案,其中一个是在LINQ语句中使用where子句:

where element.NodeType == System.Xml.XmlNodeType.CDATA

我有点看到这里发生了什么,但我不确定这是如何使用Linq(特别是从所选项目构建对象。

我是否需要单独对select语句中的项应用此过滤器?否则,我真的不明白这将如何与我正在使用的代码一起工作。

一如既往,我很感激帮助。

2 个答案:

答案 0 :(得分:8)

Cast each XElement to a string instead

reviews = from item in xmlDoc.Descendants("node")
          select new 
          {
              PubDate = (string)item.Element("created"),
              Isbn = (string)item.Element("isbn"),
              Summary = (string)item.Element("summary")
          };
// Output:
// {
//      PubDate = 2012-01-23 12:40:57,
//      Isbn = 123456789,
//      Summary = Teh Kittehs like to play in teh mud
// }

这也适用于其他数据类型,例如intfloatDateTime等:

reviews = from item in xmlDoc.Descendants("node")
          select new 
          {
              PubDate = (DateTime)item.Element("created")
          };
// Output:
// {
//      PubDate = 1/23/2012 12:40:57
// }

It also works with XAttributes as well

答案 1 :(得分:1)

请记住:

的含义没有区别
<a>
 <b>Hello</b>
 <c>&amp; hello again</c>
</a>

<a>
 <b><![CDATA[Hello]]></b>
 <c><![CDATA[& hello again]]></c>
</a>

由于您正在调用ToString()并获取整个内容 - 打开和关闭标记,实体引用等仍然是XML格式,因此您必须准备以XML格式处理它。如果没有,问题不在于您在此处显示的代码,而是PubDate"<created>2012-01-23 12:40:57</created>"且现在可以使用的代码 不完全是因为它完全等同于“”;

更改该代码以真正解析XML(框架为其提供了许多帮助),或者更改它以自行获取日期并使用Element("created").Value来检索它。