在Windows Phone上使用linq-to-xml动态构建谓词

时间:2011-12-11 00:43:39

标签: c# linq xpath linq-to-xml windows-phone-7.1

我正在开发一个Window Phone应用程序,我需要使用带有linq的xpath。不幸的是,目前不支持xpath。我有一个xml文件,当用户选择节点时,我递归地向下钻取。 node()/ @ title被加载到列表框中。用户选择等等。我通常会动态构建xpath谓词。

例如:

<cfr>
<chapter title="CHAPTER VI" volume="6">
    <subchapter title="SUBCHAPTER A" volume="6">
        <part number="600" title="PART 600">
            <subpart number="Subpart A" part="PART 600" title="Subpart A Farm Credit Administration">
                <section number="600.1" title="The Farm Credit Act." part="PART 600" link="12CFR600.1" type="cfr"/>
                <section number="600.2" title="Farm Credit Administration." part="PART 600" link="12CFR600.2" type="cfr"/>
            </subpart>
        </part>
        <part number="601" title="PART 601">
            <section number="601.1" title="The Credit Act." part="PART 601" link="12CFR6001.1" type="cfr"/>
        </part>
    </subchapter>
    <part>......</part>
</chapter>
</cfr>   

在xpath中我会使用:

/node()/node()/node()/node()[@title='PART 601']/node()[@title='The Music Act.']/@title

我会跟踪用户点击的深度和索引。我会在c#中构建xpath谓词:

 private String XpathBuilder(bool isParentNode)
    {
        int nCount = AcmSinglton.NodeCount;
        StringBuilder nodeStr = new StringBuilder();
        nodeStr.Append("/node()/node()");

        for (int i = 0; i < nCount; i++)
        {
            if (i != 0)
            {
                nodeStr.Append("[@title = '" + AcmSinglton.TitlePredicatesArrayList.get(i - 1).toString() + "']/node()");
            }
            else
            {
                nodeStr.Append("/node()");
            }
        }
        return nodeStr.ToString();
    }

所以我正在寻找使用linq-to-xml动态构建谓词的想法。

这是我到目前为止所做的:

 XDocument xml = XDocument.Load(String.Format("Resourses/c{0}x{1}.xml", this.CFRTitle, this.Volume));               
            var nodes = from x in xml.Elements().ElementAt(nodeDepth).Elements()
                        select new Menus.Chapter
                        {
                           Title = x.Attribute("title").Value
                        };

            this.MainListBox.ItemsSource = nodes.ToList();

1 个答案:

答案 0 :(得分:1)

这样的事情应该有效:

var currentLevelElements = doc.Root.Elements();
int depth = 0;
while (currentLevelElements != null && depth < nodeDepth)
{
    currentLevelElements = currentLevelElements.Elements()
                                               .Where( x=> (string) x.Attribute("title") == AcmSinglton.GetTitle(depth));
    depth++;
}
var nodes = from x in currentLevelElements select new Menus.Chapter
                    {
                       Title = x.Attribute("title").Value
                    };

查询Singleton的标题信息似乎很尴尬 - 这是一个应该直接传递给方法的依赖项。