gpt4 book ai didi

c# - 使用 XPath 选择带通配符的属性

转载 作者:行者123 更新时间:2023-11-27 23:46:18 24 4
gpt4 key购买 nike

我得到了需要解析的 HTML,我正在使用 C# 和 Html Agility Pack Library 来选择节点。我的 html 看起来像:

<input data-translate-atrr-placeholder="FORGOT_PASSWORD.FORM.EMAIL">

或:

<h1 data-translate="FORGOT_PASSWORD.FORM.EMAIL"></h1>

其中 data-translate-attr-**** 是我需要找到的新属性模式

我可以使用这样的东西:

//[contains(@??,'data-translate-attr')]

但不幸的是,这只会搜索属性内部的值。 如何使用通配符查找属性本身?

更新: @Mathias Muller

HtmlAgilityPack.HtmlDocument htmlDoc    
// this is the old code (returns nodes)
var nodes = htmlDoc.DocumentNode.SelectNodes("//@data-translate");
// these suggestions return no nodes using the same data
var nodes = htmlDoc.DocumentNode.SelectNodes("//@*[contains(name(),'data-translate')]");
var nodes = htmlDoc.DocumentNode.SelectNodes("//@*[starts-with(name(),'data-translate')]");

更新 2

这似乎是一个 Html Agility Pack 问题而不是一个 XPath 问题,我使用 chrome 来测试我的 XPath 表达式并且以下所有内容都在 chrome 中工作但在 Html Agility Pack 中不起作用:

//@*[contains(local-name(),'data-translate')]
//@*[starts-with(name(),'data-translate')]
//attribute::*[starts-with(local-name(.),'data-translate')]

我的解决方案

我最终只是以老式的方式做事......

var nodes = htmlDoc.DocumentNode.SelectNodes("//@*");

if (nodes != null) {
foreach (HtmlNode node in nodes) {
if (node.HasAttributes) {
foreach (HtmlAttribute attr in node.Attributes) {
if (attr.Name.StartsWith("data-translate")) {
// code in here to handle translation node
}
}
}
}
}

最佳答案

而不是使用 name(),使用 local-name() 例如:

var nodes = htmlDoc.DocumentNode.SelectNodes("//@*[starts-with(local-name(),'data-translate')]");

区别在于 name() 应该为您提供带有前缀的属性名称,例如 xml 中的 namespace ,而 local-name() 将发出该前缀如果它在那里,在你的情况下 name()local-name() 应该以相同的方式工作,因为它的 html 并且没有 namespace ,但它们似乎没有't,它可能是一个错误。

测试:

    var html = "<h3 x='foo'></h3>";
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
var ElementByName = doc.DocumentNode.SelectSingleNode("//*[name()='h3']"); //Works
var ElementByLocalName = doc.DocumentNode.SelectSingleNode("//*[local-name()='h3']"); //Works
var ElementByAttributeLocalName = doc.DocumentNode.SelectSingleNode("//*[@*[local-name()='x']]"); //Works
var ElementByAttributeName = doc.DocumentNode.SelectSingleNode("//*[@*[name()='x']]"); //Does NOT

//Mathias Way
var ElementByAttributeLocalName_ = doc.DocumentNode.SelectSingleNode("//@*[local-name() = 'x']"); //Works
var ElementByAttributeName_ = doc.DocumentNode.SelectSingleNode("//@*[name() = 'x']"); //Does NOT

关于c# - 使用 XPath 选择带通配符的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29802310/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com