Permalink
Browse files

XPath: need not-equivalence operator ( elem[ @attr != "value" ] )

  • Loading branch information...
1 parent 6abffff commit 42506e8ab36d5d860ef0ff06ea00f9d05783b550 @the-Arioch the-Arioch committed Jul 20, 2016
Showing with 17 additions and 9 deletions.
  1. +17 −9 OmniXMLXPath.pas
View
@@ -125,7 +125,7 @@ TXMLXPathEvaluator = class
procedure EvaluatePart(startList: IXMLNodeList; const element, predicate: XmlString;
flags: TXMLXPathElementFlags; endList: IXMLNodeList);
procedure FilterByAttrib(startList: IXMLNodeList; const attribName, attribValue:
- XmlString; endList: IXMLNodeList);
+ XmlString; const NotEQ: boolean; endList: IXMLNodeList);
procedure FilterByChild(startList: IXMLNodeList; const childName,
childValue: XmlString; endList: IXMLNodeList);
procedure FilterNodes(startList: IXMLNodeList; const predicate: XmlString;
@@ -282,7 +282,7 @@ procedure TXMLXPathEvaluator.EvaluatePart(startList: IXMLNodeList; const element
@since 2005-10-28
}
procedure TXMLXPathEvaluator.FilterByAttrib(startList: IXMLNodeList; const attribName,
- attribValue: XmlString; endList: IXMLNodeList);
+ attribValue: XmlString; const NotEQ: boolean; endList: IXMLNodeList);
var
attrNode : IXMLNode;
iNode : integer;
@@ -291,7 +291,7 @@ procedure TXMLXPathEvaluator.FilterByAttrib(startList: IXMLNodeList; const attri
matchAnyValue := (attribValue = '*');
for iNode := 0 to startList.Length-1 do begin
attrNode := startList.Item[iNode].Attributes.GetNamedItem(attribName);
- if assigned(attrNode) and (matchAnyValue or (attrNode.NodeValue = attribValue)) then
+ if assigned(attrNode) and (matchAnyValue or ((attrNode.NodeValue = attribValue) xor NotEQ )) then
endList.Add(startList.Item[iNode]);
end;
end; { TXMLXPathEvaluator.FilterByAttrib }
@@ -367,9 +367,9 @@ procedure TXMLXPathEvaluator.FilterNodes(startList: IXMLNodeList; const
else begin
SplitExpression(Copy(predicate, 2, Length(predicate)-1), left, op, right);
if op = '' then // [@attrib]
- FilterByAttrib(startList, left, '*', endList)
- else if op = '=' then // [@attrib='x']
- FilterByAttrib(startList, left, right, endList)
+ FilterByAttrib(startList, left, '*', false, endList)
+ else if (op = '=') or (op = '!=') then // [@attrib='x']
+ FilterByAttrib(startList, left, right, op = '!=', endList)
else
raise EXMLXPath.CreateFmt('Unsupported operator [%s]', [predicate]);
end;
@@ -458,7 +458,7 @@ function TXMLXPathEvaluator.PosEx(ch: WideChar; const s: XmlString; offset: inte
procedure TXMLXPathEvaluator.SplitExpression(const predicate: XmlString; var left, op,
right: XmlString);
var
- pOp: integer;
+ pOp, pOpLen: integer;
begin
pOp := Pos('=', predicate);
if pOp = 0 then begin
@@ -467,9 +467,17 @@ procedure TXMLXPathEvaluator.SplitExpression(const predicate: XmlString; var lef
right := '';
end
else begin
+ pOpLen := 1;
+ if pOp > 1 then // != operator ???
+ if predicate[pOp-1] = '!' then begin
+ Inc(pOpLen);
+ Dec(pOp);
+ end;
+
left := Trim(Copy(predicate, 1, pOp-1));
- op := predicate[pOp];
- right := Trim(Copy(predicate, pOp+1, Length(predicate)-pOp));
+ // op := predicate[pOp];
+ op := Copy(predicate, pOp, pOpLen);
+ right := Trim(Copy(predicate, pOp+pOpLen, Length(predicate)));
if (right[1] = '''') and (right[Length(right)] = '''') then
right := Copy(right, 2, Length(right)-2)
else if (right[1] = '"') and (right[Length(right)] = '"') then

0 comments on commit 42506e8

Please sign in to comment.