質問

私は(私はWYSIWYGのXSLエディタを書いていたように)のXPathのための「AET」(抽象的な表現ツリー)を作成しようとしています。私は過去3〜4時間のXPath BNFと壁に頭を打ってきた。

私は別の解決策を考えています。私はCreateNavigatorが呼び出されたときに自分ののXPathNavigatorを返しIXPathNavigableを実装するクラスを書くことができると思いました。これのXPathNavigatorは、常に任意のメソッドの呼び出しに成功すると、これらの呼び出しを追跡するだろう - たとえば、我々は、顧客ノードと、顧客のノードに移動しました。私は、(私たちは今、オブジェクトモデルで顧客/顧客を持っているでしょう)「AET」を作成するために、(うまくいけば)、この情報を使用することができます。

のみ質問です:どのようにの地球の私はXPathExpressionてIXPathNavigableを実行してください。

私は、これが過度に怠惰である知っています。しかし、誰にも努力を経およびXPath式パーサーを書いていますか? (私はIXPathNavigableに対してXPathExpressionを実行することはできませんので)、私はそれをテストすることはできませんので、私の解決策でも動作する場合、私も知らないので、私はまだ、私の可能な解決策をPOC'dしていない。

役に立ちましたか?

解決

ここでANTLRのXPath文法がありますする 。そのライセンス許可ので、私は将来的にリンク切れを避けるために、ここで全体の文法をコピーします。

grammar xpath;

/*
XPath 1.0 grammar. Should conform to the official spec at
http://www.w3.org/TR/1999/REC-xpath-19991116. The grammar
rules have been kept as close as possible to those in the
spec, but some adjustmewnts were unavoidable. These were
mainly removing left recursion (spec seems to be based on
LR), and to deal with the double nature of the '*' token
(node wildcard and multiplication operator). See also
section 3.7 in the spec. These rule changes should make
no difference to the strings accepted by the grammar.
Written by Jan-Willem van den Broek
Version 1.0
Do with this code as you will.
*/
/*
    Ported to Antlr4 by Tom Everett <tom@khubla.com>
*/


main  :  expr
  ;

locationPath 
  :  relativeLocationPath
  |  absoluteLocationPathNoroot
  ;

absoluteLocationPathNoroot
  :  '/' relativeLocationPath
  |  '//' relativeLocationPath
  ;

relativeLocationPath
  :  step (('/'|'//') step)*
  ;

step  :  axisSpecifier nodeTest predicate*
  |  abbreviatedStep
  ;

axisSpecifier
  :  AxisName '::'
  |  '@'?
  ;

nodeTest:  nameTest
  |  NodeType '(' ')'
  |  'processing-instruction' '(' Literal ')'
  ;

predicate
  :  '[' expr ']'
  ;

abbreviatedStep
  :  '.'
  |  '..'
  ;

expr  :  orExpr
  ;

primaryExpr
  :  variableReference
  |  '(' expr ')'
  |  Literal
  |  Number  
  |  functionCall
  ;

functionCall
  :  functionName '(' ( expr ( ',' expr )* )? ')'
  ;

unionExprNoRoot
  :  pathExprNoRoot ('|' unionExprNoRoot)?
  |  '/' '|' unionExprNoRoot
  ;

pathExprNoRoot
  :  locationPath
  |  filterExpr (('/'|'//') relativeLocationPath)?
  ;

filterExpr
  :  primaryExpr predicate*
  ;

orExpr  :  andExpr ('or' andExpr)*
  ;

andExpr  :  equalityExpr ('and' equalityExpr)*
  ;

equalityExpr
  :  relationalExpr (('='|'!=') relationalExpr)*
  ;

relationalExpr
  :  additiveExpr (('<'|'>'|'<='|'>=') additiveExpr)*
  ;

additiveExpr
  :  multiplicativeExpr (('+'|'-') multiplicativeExpr)*
  ;

multiplicativeExpr
  :  unaryExprNoRoot (('*'|'div'|'mod') multiplicativeExpr)?
  |  '/' (('div'|'mod') multiplicativeExpr)?
  ;

unaryExprNoRoot
  :  '-'* unionExprNoRoot
  ;

qName  :  nCName (':' nCName)?
  ;

functionName
  :  qName  // Does not match nodeType, as per spec.
  ;

variableReference
  :  '$' qName
  ;

nameTest:  '*'
  |  nCName ':' '*'
  |  qName
  ;

nCName  :  NCName
  |  AxisName
  ;

NodeType:  'comment'
  |  'text'
  |  'processing-instruction'
  |  'node'
  ;

Number  :  Digits ('.' Digits?)?
  |  '.' Digits
  ;

fragment
Digits  :  ('0'..'9')+
  ;

AxisName:  'ancestor'
  |  'ancestor-or-self'
  |  'attribute'
  |  'child'
  |  'descendant'
  |  'descendant-or-self'
  |  'following'
  |  'following-sibling'
  |  'namespace'
  |  'parent'
  |  'preceding'
  |  'preceding-sibling'
  |  'self'
  ;


  PATHSEP 
       :'/';
  ABRPATH   
       : '//';
  LPAR   
       : '(';
  RPAR   
       : ')';
  LBRAC   
       :  '[';
  RBRAC   
       :  ']';
  MINUS   
       :  '-';
  PLUS   
       :  '+';
  DOT   
       :  '.';
  MUL   
       : '*';
  DOTDOT   
       :  '..';
  AT   
       : '@';
  COMMA  
       : ',';
  PIPE   
       :  '|';
  LESS   
       :  '<';
  MORE_ 
       :  '>';
  LE   
       :  '<=';
  GE   
       :  '>=';
  COLON   
       :  ':';
  CC   
       :  '::';
  APOS   
       :  '\'';
  QUOT   
       :  '\"';

Literal  :  '"' ~'"'* '"'
  |  '\'' ~'\''* '\''
  ;

Whitespace
  :  (' '|'\t'|'\n'|'\r')+ ->skip
  ;

NCName  :  NCNameStartChar NCNameChar*
  ;

fragment
NCNameStartChar
  :  'A'..'Z'
  |   '_'
  |  'a'..'z'
  |  '\u00C0'..'\u00D6'
  |  '\u00D8'..'\u00F6'
  |  '\u00F8'..'\u02FF'
  |  '\u0370'..'\u037D'
  |  '\u037F'..'\u1FFF'
  |  '\u200C'..'\u200D'
  |  '\u2070'..'\u218F'
  |  '\u2C00'..'\u2FEF'
  |  '\u3001'..'\uD7FF'
  |  '\uF900'..'\uFDCF'
  |  '\uFDF0'..'\uFFFD'
// Unfortunately, java escapes can't handle this conveniently,
// as they're limited to 4 hex digits. TODO.
//  |  '\U010000'..'\U0EFFFF'
  ;

fragment
NCNameChar
  :  NCNameStartChar | '-' | '.' | '0'..'9'
  |  '\u00B7' | '\u0300'..'\u036F'
  |  '\u203F'..'\u2040'
  ;

他のヒント

私は両方(Iは XMLPrime の現像剤にするために使用するXPathパーサーとIXPathNavigableの実装を書かれています)。どちらも簡単ではありません。そして、私はIXPathNavigableは異なる方法間の相互作用における微妙なのかなり多くがあるので、あなたが期待し安い勝利であることを行っていないと思われる - 。私は本格的なXPathのパーサは単純(そしてより信頼性の高い)になります疑い

しかし、あなたの質問に答えるために:

var results xpathNavigable.CreateNavigator().Evaluate("/my/xpath[expression]").

あなたはおそらくノードがナビゲートさせるように結果の上に列挙するために必要があると思います。

foo[not(bar)]/other/elements

:あなたは常にtrueを返した場合は、

あなたは次のXPathについて知っているだろうすべては、それがfooのバー子供たちのために見えるということです

あなたは常に、ノードの固定数を返すなら、あなたはこののXPath a[100]/b/c/のほとんどについて知っていることがありませんでした。

基本的に、これは動作しません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top