【问题标题】:Find XmlNode where attribute value is contained in string查找字符串中包含属性值的 XmlNode
【发布时间】:2012-06-29 14:20:51
【问题描述】:

我有一个 xml 文件...

<?xml version="1.0" encoding="UTF-8"?>
<items defaultNode="1">
    <default contentPlaceholderName="pageContent" template="" genericContentItemName="" />
    <item urlSearchPattern="connections-learning" contentPlaceholderName="pageContent" template="Connections Learning Content Page" genericContentItemName="" />
    <item urlSearchPattern="online-high-school" contentPlaceholderName="pageContent" template="" genericContentItemName="" />
</items>

我正在尝试查找字符串urlSearchPattern 中包含urlSearchPattern 属性的第一个节点。我遇到麻烦的地方是找到 属性包含在字符串值中的节点,而不是 字符串值包含在属性中

到目前为止,这是我的尝试。这将找到属性中包含字符串值的 firstOrDefault 节点(我需要相反)...

string urlSearchPattern = Request.QueryString["aspxerrorpath"];
MissingPageSettingsXmlDocument missingPageSettingsXmlDocument = new MissingPageSettingsXmlDocument();
XmlNode missingPageItem = missingPageSettingsXmlDocument.SelectNodes(ITEM_XML_PATH).Cast<XmlNode>().Where(item => item.Attributes["urlSearchPattern"].ToString().ToLower().Contains(urlSearchPattern)).FirstOrDefault();

【问题讨论】:

  • 您能否举例说明您期望的输出,我不理解您所说的“属性包含在字符串值中”和“字符串值包含在属性中”的意思跨度>

标签: c# xml linq xml-parsing


【解决方案1】:

嗯...然后反转!

var result = missingPageSettingsXmlDocument
                .SelectNodes(ITEM_XML_PATH)
                .Cast<XmlNode>()
                .FirstOrDefault(
                    m => m.Attributes != null && 
                    m.Attributes["urlSearchPattern"] != null && 
                    urlSearchPattern.Contains(m.Attributes["urlSearchPattern"].ToString().ToLower())
                 );

【讨论】:

    【解决方案2】:

    使用这个Xml Library,并提供您的 ITEM_XML_PATH 看起来像://item

    XElement root = XElement.Load(file); // or .Parse(string)
    var matches = root.XPath("//item[contains({0}, {1}, false)]", 
        urlSearchPattern, new NodeSet("@urlSearchPattern"));
    

    false 表示用.ToLower() 转换所有值并用节点集反转模式,它将搜索pattern.Contains(nodeset)

    如果您的项目没有 urlSearchPattern 或者它们的值为 "",您可以将 and . != '' 添加到 xpath 表达式以从结果中删除它们。

    该库还处于起步阶段,因此如果您的 ITEM_XML_PATH 非常复杂,这可能不适合您。

    更新:基于 Pawel 的 cmets,使用包含的 Linq-to-Xml XPath 版本:

    root.XPathSelectElements(
        "//item[contains('" + urlSearchPattern + "', @urlSearchPattern)]");
    

    【讨论】:

    • Linq to Xml 内置了对 XPath 的支持:msdn.microsoft.com/en-us/library/bb675178
    • @Pawel 据我所知,它不支持类型安全。阿卡,你能做到root.XPath("people/person[@Birth&lt;={0}]", DateTime.Now.AddYears(-30));吗?
    • Linq to Xml 是在 .NET Framework 3.5 中引入的。我没有再安装 VS2008 来检查,但我很确定它在那里也能正常工作 - 这是我之前发布的一个链接,但它适用于 .NET Framework 3.5。 msdn.microsoft.com/en-us/library/bb675178(v=vs.90)。我不太确定您的意思,但类型安全但您可以使用 string.Format 来防止 XPath 注入攻击。此外,Linq to Xml 为 XElement 和 XAttribute 提供了显式转换运算符(例如 msdn.microsoft.com/en-us/library/system.xml.linq.xattribute),因此您可以强制转换为强类型
    • 这就是库所做的,根据提供的类型自动为您转换和比较。
    • @Pawel Thx Pawel,我调整了答案以包括 Linq-to-Xml 版本,因为他们不需要使用库。
    猜你喜欢
    • 2023-02-25
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 2017-06-13
    • 2011-04-06
    相关资源
    最近更新 更多