我有以下代码来查找所需节点的类型。
private void handleDemote(CalendarCustomization calendar)
{
String name = calendar.getName();
Node node = (Node)reader.read("/APIBusinessObjects/Calendar[Name='" + name + "']/Type", XPathConstants.NODE);
...}
public Object read(String expression, QName returnType)
{
try
{
XPathExpression xPathExpression = xPath.compile(expression);
return xPathExpression.evaluate(xmlDocument, returnType);
}
catch (XPathExpressionException ex)
{
ex.printStackTrace();
return null;
}
}
我想解析的xml有以下内容
<Calendar>
<BaseCalendarObjectId xsi:nil="true" />
<HoursPerDay>8</HoursPerDay>
<HoursPerMonth>173.3</HoursPerMonth>
<HoursPerWeek>40</HoursPerWeek>
<HoursPerYear>2080</HoursPerYear>
<IsDefault>0</IsDefault>
<IsPersonal>0</IsPersonal>
<Name>test'sCal</Name>
getName函数返回test'sCal.So name = test'sCal。 问题在于撇号,因为表达式包含单个额外引用。它缩短了导致表达式出错的名称。 请建议。
答案 0 :(得分:1)
您需要在表达式中使用双引号。
(Node)reader.read("/APIBusinessObjects/Calendar[Name=\"" + name + "\"]/Type", XPathConstants.NODE);
答案 1 :(得分:1)
根据this answer,您应该能够在Java中使用XPath变量,这是解决此问题的正确方法。
您可以定义通用变量解析器:
class MapVariableResolver implements XPathVariableResolver {
// local store of variable name -> variable value mappings
Map<String, String> variableMappings = new HashMap<String, String>();
// a way of setting new variable mappings
public void setVariable(String key, String value) {
variableMappings.put(key, value);
}
// override this method in XPathVariableResolver to
// be used during evaluation of the XPath expression
@Override
public Object resolveVariable(QName varName) {
// if using namespaces, there's more to do here
String key = varName.getLocalPart();
return variableMappings.get(key);
}
}
修改您的read()
方法,如下所示:
public Object read(String expression, QName returnType, XPathVariableResolver vr)
{
try
{
xPath.setXPathVariableResolver(vr != null ? vr : new MapVariableResolver());
XPathExpression xPathExpression = xPath.compile(expression);
return xPathExpression.evaluate(xmlDocument, returnType);
}
catch (XPathExpressionException ex)
{
ex.printStackTrace();
return null;
}
}
然后执行此操作:
String name = calendar.getName();
MapVariableResolver vr = new MapVariableResolver() ;
vr.setVariable("name", name);
Node node = (Node)reader.read("/APIBusinessObjects/Calendar[Name = $name]/Type",
XPathConstants.NODE, vr);
答案 2 :(得分:0)
对于一般解决方案(即,当您不知道输入是否包含单引号,双引号或两者)时:
如果你有XPath 2.0,我猜你不用你的Java代码判断,你可以用一对单引号替换每个单引号(用单引号分隔的字符串,就像你的那样)。 (见this answer。)
否则,您可以在XPath表达式中使用concat()
根据需要将'"'
和"'"
与其余字符串连接起来。见The Perils of XPath Expressions (Specifically, Escaping Quotes)。因此,对于您的示例数据,您的XPath表达式将显示为:
-
/APIBusinessObjects/Calendar[Name = concat('test', "'", 'sCal')]
然后由您编写Java函数将test'sCal
转换为'test', "'", 'sCal'
。值得庆幸的是,concat()
将提供与您提供的一样多的参数。