Rya*_*yan 27 c# xml xpath xpath-1.0
XPath(v1)无法编码表达式.
如果您只有单个OR双引号,那么您可以使用诸如的单词
//review[@name="Bob's Pizza"]
//review[@name='"Pizza" Pam']
Run Code Online (Sandbox Code Playgroud)
但是如果你有两个例如[弗雷德的"Fancy Pizza"]那么你必须在XPath(C++)中使用像Escaping Strings这样的东西来生成
//review[@name=Concat("Fred's ",'"Fancy Pizza"')]
Run Code Online (Sandbox Code Playgroud)
任何人都有c#函数来执行此操作?
一些链接很接近
编辑:一些答案建议转义'with '
和',"
但虽然这是有道理的,它不起作用;尝试使用XML片段:
<review name="Bob's Pizza"/>
Run Code Online (Sandbox Code Playgroud)
和xpath
//review[@name='Bob's Pizza']
Run Code Online (Sandbox Code Playgroud)
小智 11
哇,你们都肯定会让这个变得复杂.为什么不这样做呢?
public static string XpathExpression(string value)
{
if (!value.Contains("'"))
return '\'' + value + '\'';
else if (!value.Contains("\""))
return '"' + value + '"';
else
return "concat('" + value.Replace("'", "',\"'\",'") + "')";
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*ney 10
虽然它肯定不会在所有情况下都起作用,但这是一种回避问题的方法:
doc.DocumentElement.SetAttribute("searchName", name);
XmlNode n = doc.SelectNodes("//review[@name=/*/@searchName]");
Run Code Online (Sandbox Code Playgroud)
小智 7
我需要这个,所以我为C#创建了这个解决方案.
/// <summary>
/// Returns a valid XPath statement to use for searching attribute values regardless of 's or "s
/// </summary>
/// <param name="attributeValue">Attribute value to parse</param>
/// <returns>Parsed attribute value in concat() if needed</returns>
public static string GetXpathStringForAttributeValue(string attributeValue)
{
bool hasApos = attributeValue.Contains("'");
bool hasQuote = attributeValue.Contains("\"");
if (!hasApos)
{
return "'" + attributeValue + "'";
}
if (!hasQuote)
{
return "\"" + attributeValue + "\"";
}
StringBuilder result = new StringBuilder("concat(");
StringBuilder currentArgument = new StringBuilder();
for (int pos = 0; pos < attributeValue.Length; pos++)
{
switch (attributeValue[pos])
{
case '\'':
result.Append('\"');
result.Append(currentArgument.ToString());
result.Append("'\",");
currentArgument.Length = 0;
break;
case '\"':
result.Append('\'');
result.Append(currentArgument.ToString());
result.Append("\"\',");
currentArgument.Length = 0;
break;
default:
currentArgument.Append(attributeValue[pos]);
break;
}
}
if (currentArgument.Length == 0)
{
result[result.Length - 1] = ')';
}
else
{
result.Append("'");
result.Append(currentArgument.ToString());
result.Append("')");
}
return result.ToString();
}
Run Code Online (Sandbox Code Playgroud)
这是我想出的
public static string EncaseXpathString(string input)
{
// If we don't have any " then encase string in "
if (!input.Contains("\""))
return String.Format("\"{0}\"", input);
// If we have some " but no ' then encase in '
if (!input.Contains("'"))
return String.Format("'{0}'", input);
// If we get here we have both " and ' in the string so must use Concat
StringBuilder sb = new StringBuilder("concat(");
// Going to look for " as they are LESS likely than ' in our data so will minimise
// number of arguments to concat.
int lastPos = 0;
int nextPos = input.IndexOf("\"");
while (nextPos != -1)
{
// If this is not the first time through the loop then seperate arguments with ,
if (lastPos != 0)
sb.Append(",");
sb.AppendFormat("\"{0}\",'\"'", input.Substring(lastPos, nextPos - lastPos));
lastPos = ++nextPos;
// Find next occurance
nextPos = input.IndexOf("\"", lastPos);
}
sb.Append(")");
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
使用类似的东西调用
XmlNode node = doc.SelectSingleNode("//review[@name=" + EncaseXpathString("Fred's \"Fancy Pizza\"" + "]")
Run Code Online (Sandbox Code Playgroud)
所以我们得到以下结果
EncaseXpathString("Pizza Shed") == "'Pizza Shed'";
EncaseXpathString("Bob's pizza") == "\"Bob's Pizza\"";
EncaseXpathString("\"Pizza\" Pam" == "'\"Pizza\" Pam'";
EncaseXpathString("Fred's \"Fancy Pizza\"") == "concat(\"Fred's \",'\"',\"Fancy Pizza\",'\"')";
Run Code Online (Sandbox Code Playgroud)
所以它只在必要时使用 concat(字符串中的 " 和 ' )
最后的结果显示 concat 操作没有想象的那么短(见问题),但它足够接近,任何更优化的东西都会非常复杂,因为你必须寻找匹配的“或”对。
归档时间: |
|
查看次数: |
26174 次 |
最近记录: |