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

发布于 2024-12-20 09:07:15 字数 2331 浏览 0 评论 0原文

我正在开发一个 Window Phone 应用程序,我需要将 xpath 与 linq 一起使用。不幸的是,当前不支持 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();

I am working on a Window Phone app were I need to use xpath with linq. Unfortunately xpath is not currently supported. I have an xml file that I recursively drill down as the user select nodes. The node()/@title is loaded into a listbox. The user selects and so-on. I normally would dynamically build the xpath predicates.

For example:

<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>   

In xpath I would use:

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

I keep track of how deep the user has clicked and which index. I would build the xpath predicate like so in c#:

 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();
    }

So I am looking for idea to dynamically build predicates using linq-to-xml.

Here is what I have so far:

 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();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

另类 2024-12-27 09:07:15

像这样的东西应该可以工作:

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
                    };

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

Something like this should work:

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
                    };

It seems awkward to query a Singleton for the title information - this is a dependency that should be passed into your method directly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文