Scalaã¯çŽ æŽãããèšèªã§ãã ããªãã¯åœŒã«æãããããšãã§ããŸãã ã³ãŒãã¯ç°¡æœã§ãããçè§£ã§ããå ŽåããããŸãã æè»ã§ããã匷ãåä»ããããŠããŸãã 培åºçã«èãåºãããããŒã«ã䜿çšãããšãèšèªãšæŠãã®ã§ã¯ãªããèšèªã§ã¢ã€ãã¢ã衚çŸã§ããŸãã
ãããããããã®åãããŒã«ã䜿çšãããšãéåžžã«è€éãªã³ãŒããäœæã§ããŸãã
scalazã¹ã¿ã€ã«ã®ã¹ããŒããã©ã³ã·ã³ã°ãŸãã¯äžå®åã³ã³ãã¥ãŒãã£ã³ã°ã䜿çšãããšããŠããããã³ãŒããçè§£ããããšãä¿èšŒãããŸãã
ãã®èšäºã§ã¯ãäœãããã¹ããã«ã€ããŠè©±ããŸãã
Scalaã«ç°ãªãèšèªãåãèŸŒãæ¹æ³ã説æããŸãã
XPathãšç§ã¯åã蟌ã¿ãŸããã説æããæ¹æ³ã¯ãæ§æããªãŒãæ§ç¯ã§ãããã¹ãŠã®èšèªã«é©ããŠããŸãã
çç±
Scalaã«ã¯ãJavaã«ããxmlãæäœããããã®ãã¹ãŠã®ããŒã«ã䜿çšããæ©èœããããŸãïŒå€ãã®ããŒã«ããããŸãïŒã ããããã³ãŒãã¯å€ãè¯ãJavaã³ãŒããæãåºãããŸãã ããŸã幞ãã§ã¯ãªãèŠéãã
èšèªæ§æã«çµã¿èŸŒãŸãããã€ãã£ãxmlããããŸãã
scala> <root> | <node attr="aaa"/> | <node attr="111"> text</node> | </root> res0: scala.xml.Elem = <root> <node attr="aaa"/> <node attr="111"> text</node> </root> scala> res0 \\ "node" res1: scala.xml.NodeSeq = NodeSeq(<node attr="aaa"/>, <node attr="111"> text</node>) scala> res1 \\ "@attr" res2: scala.xml.NodeSeq = NodeSeq(aaa, 111)
ããã¯å¹žãã®ããã§ãããéããŸãã ãªã¢ãŒãã§ã®ã¿XPathã«äŒŒãŠããŸãã å°ãè€éãªã¯ãšãªã¯é¢åã§èªã¿ã«ãããªããŸããã
ããããscalaãããçšåºŠç¥ã£ãåŸãäœæè
ãæ ¹æ ãªãscalaãã¹ã±ãŒã©ãã«ãªèšèªãšåŒãã§ããªãããšãæããã«ãªããŸããã ãããŠãäœããæ¬ ããŠããå Žåãããã远å ã§ããŸãã
èšèªãžã®äŸ¿å©ãªçµ±åã«ãããã¿ã¹ã¯ãå¯èœãªéãXPathã«è¿ã¥ããŸãã
çµæ
ããã§ã®ãã¹ãŠã®éçºïŒ
https :
//github.com/senia-psm/scala-xpath.gitèŠæ¹gitãšsbtããŸã ãªãå Žåã¯ãããããã€ã³ã¹ããŒã«ããå¿
èŠãããïŒ
git ã
sbt ïŒãå¿
èŠã«å¿ããŠããããã·ãæ§æããå¿
èŠããããŸãïŒ
git ã
sbt -Program FilesïŒx86ïŒ\ SBT \ãã®ãããªãªãã·ã§ã³ã®ããã®ç¹å¥ãªtxtããããŸãïŒã
ãªããžããªã®ã¯ããŒã³ãäœæããŸãã
git clone https://github.com/senia-psm/scala-xpath.git
ãªããžããªïŒscala-xpathïŒããããã©ã«ããŒã«ç§»åãããããžã§ã¯ãã§REPLãéããŸãã
sbt console
ãŸããå€ãã®äŸã§ã¯ã次ã®ã€ã³ããŒããå®è¡ãããŠãããšæ³å®ãããŠããŸãã
import senia.scala_xpath.macros._, senia.scala_xpath.model._
äœãšã©ã®ããã«
ç®æšãéæããæ¹æ³ã¯ãç®æšèªäœã«ãã£ãŠäžæã«æ±ºå®ãããŸãã
XPathãDSLãšããŠåã蟌ãããšã¯æããã«å€±æããŸãã ããããªããšãXPathã§ã¯ãªããªããŸãã scalaã®XPathåŒã¯æååãšããŠã®ã¿é
眮ã§ããŸãã
ã€ãŸãïŒ
- ããŒãµãŒã³ã³ãããŒã¿ãŒ ã æ€èšŒã®ããã«æååãè§£æããå¿
èŠããããŸãã
- ã¹ããªã³ã°è£é ã XPathã«å€æ°ãšé¢æ°ãåã蟌ãããã
- ãã¯ã ã³ã³ãã€ã«æ®µéã§ã®æ€èšŒçšã
ãªããžã§ã¯ãã¢ãã«ãæºåããŸãã
XPath 1.0仿§ãåãäžããŠ
ã scalaã§
æžãçŽããŠãã ããã
ã»ãšãã©ãã¹ãŠã®ããžãã¯ã¯ãåã·ã¹ãã ãšscalaã®ç¶æ¿ã¡ã«ããºã ã«ãã£ãŠè¡šçŸãããŸãã äŸå€ã¯ãrequireãä»ããå¶éã®ããã€ãã®å Žæã«ãããŸãã
ããã§ã¯ããã®ãã¡ã€ã«ã®å€éšã§ã¯ã©ã¹ãç¶æ¿ããïŒãŸãã¯ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããïŒããšãçŠæ¢ãããsealedãããŒã¯ãŒãã«æ³šç®ãã䟡å€ããããŸãã ç¹ã«ããµã³ãã«ãšæ¯èŒããå Žåããã·ãŒã«ãã䜿çšãããšãã³ã³ãã€ã©ã¯ãã¹ãŠã®å¯èœãªãªãã·ã§ã³ãèæ
®ãããŠããããšã確èªã§ããŸãã
Parsim XPath
ããŒãµãŒã®ç޹ä»ããŒãµãŒã¯ãäžé£ã®èŠçŽ ãåããæåããå ŽåãåŠççµæãšæ®ãã®ã·ãŒã±ã³ã¹ãè¿ã颿°ã§ãã
ãã ãã倱æããçµæã«ã¯ãã倱æããšããšã©ãŒãã®2ã€ã®åœ¢åŒããããŸãã
æ¯Figçã«èšãã°ãããŒãµãŒã¯ã·ãŒã±ã³ã¹ã®äžéšãæåããåã¿ãåãŸãããã®ãç¹å®ã®ã¿ã€ãã®ãªããžã§ã¯ãã«å€æããŸãã
æãåçŽãªããŒãµãŒã¯ãã·ãŒã±ã³ã¹ã®æåã®èŠçŽ ãæå®ã®èŠçŽ ãšçããããšã確èªãããã®èŠçŽ ãæåããçµæãšããŠè¿ãããŒãµãŒã§ãã æ®ããšããŠããã®èŠçŽ ã®ãªãã·ãŒã±ã³ã¹ããããŸãã
èŠçŽ ãããã®ãããªããŒãµãŒãäœæããã«ã¯ãèŠçŽ ãåãå
¥ããacceptã¡ãœããã䜿çšããŸãã ãã®ã¡ãœããã¯æé»çãšããŠå®çŸ©ãããŠãããã³ã³ãã€ã©ãããŒãµãŒã«äŒããšäºæ³ãããèŠçŽ ã«ééããå Žåããã®ã¡ãœããã®ã¢ããªã±ãŒã·ã§ã³ãèŠçŽ ã«è¿œå ããŸãã
æåã®ã·ãŒã±ã³ã¹ãè§£æãããšããŸãããïŒ
def elementParser: Parser[Char] = 'c'
ãããã£ãŠãããŒãµãŒãçµã¿åããããšãã«ãããŒãµãŒãããã¹ãå Žæã«èŠçŽ ãããå Žåããã®ãããªåºæ¬çãªããŒãµãŒãããã«ããããšãç¥ã£ãŠããŸãã
äžè¬ã«ãããã¯æç€ºçã«å®çŸ©ãããå¯äžã®ããŒãµãŒã§ãã
ä»ã®ãã¹ãŠã®ããŒãµãŒã¯ãä»ã®ããŒãµãŒãšçµæå€æã®çµã¿åããã«ãã£ãŠååŸãããŸãã
ããŒãµãŒãçµã¿åããã
åã®ããã«ããå®éãscalaã«ã¯æŒç®åã¯ãããŸãããããããç¥ã£ãŠããã°ãããããããŒãµãŒã«ã€ããŠè©±ãå¿
èŠã¯ãããŸããã
äºé
æŒç®åã¯ãããã§ãã ãandãã®ååã«åŸã£ãŠ2ã€ã®ããŒãµãŒãçµã¿åãããŸãã æåã®ããŒãµãŒãæåããå Žåã«ã®ã¿æåãããã®åŸãæåã®ããŒãµãŒãè§£æããæ®ãã®2çªç®ã®ããŒãµãŒãæåããŸãã
æ¯urçã«èšãã°ãæåã®ããŒãµãŒãæåã«åœŒã«åã£ããã®ãåã¿ã次ã«2çªç®ã®ããŒãµãŒãæ®ãç©ãé£ã¹ãŸãã
äž¡æ¹ã®ããŒãµãŒã®çµæãå«ãã³ã³ãããŒãçµæãšããŠè¿ãããŸãã
parser1 ~ parser2
ãã®æ¹æ³ã§ãããŒãµãŒã®ä»»æã®ã»ãããçµã¿åãããããšãã§ããŸãã
ãã®ã³ã³ãããŒã¿ã«ã¯ããã>ããšã<ããã®2ã€ã®å
åŒããããŸãã ãããã¯åãããã«æ©èœããŸãããçµã¿åãããããŒãµãŒã®1ã€ã ãã®çµæãè¿ããŸãã
äºé
æŒç®åã|ãã ããŸãã¯ãã«åºã¥ãé¢é£ä»ãã å°ãªããšã1ã€ã®çµæãåæå
¥åã§æåããå Žåã¯æåã§ãã æåã®ããŒãµãŒãã倱æããè¿ããå ŽåïŒãšã©ãŒã§ã¯ãªãïŒãåãå
¥åã2çªç®ã®ããŒãµãŒã«ãã£ãŒãããããšããŸãã
æ
åœè
ã·ãŒã±ã³ã¹ã ããŒãµãŒãmyParserããããå ŽåããrepïŒmyParserïŒãã䜿çšããŠäœæãããããŒãµãŒã¯ãå
¥åããæåã®å€±æããã¢ããªã±ãŒã·ã§ã³ãžã®ãmyParserãã®å©ããåããŠããã€ããããŸãã ãã¹ãŠã®ããã€ããã®çµæã¯ãã³ã¬ã¯ã·ã§ã³ã«çµåãããŸãã
空ã§ãªãçµæã³ã¬ã¯ã·ã§ã³ïŒrep1ïŒããã³åºåãã·ãŒã±ã³ã¹ïŒrepsepïŒã«ã¯ãé¢é£ãã倿ããããŸã
çµæã倿ãã
è§£æã®çµæã«å¯ŸããŠå€æãå®è¡ããå¿
èŠãããå Žåã¯ã^^^ã^^ãªã©ã®æŒç®åã圹ç«ã¡ãŸã
^^^ã¯çµæãæå®ããã宿°ã«å€æŽãã^^ã¯æå®ããã颿°ã䜿çšããŠçµæã倿ããŸãã
ããŒãµãŒã®çµã¿åããïŒããã³w3c仿§ã®ãªãã©ã·ãŒïŒã«ãããããããããšãªãããŒãµãŒãäœæã§ããŸãã
å®éã仿§ã2åæžãæããŠããŸãã å¯äžã®å€§ããªéãã¯ãååž°çãªå®çŸ©ãã埪ç°ãå®çŸ©ïŒrepããã³repsepïŒã«çœ®ãæããããšã§ãã
äŸïŒ
仿§ïŒ
[15] PrimaryExpr :: = VariableReference
| 'ïŒ' Expr 'ïŒ'
| ãªãã©ã«
| æ°
| 颿°åŒã³åºã
ããŒãµãŒ ïŒ
def primaryExpr: Parser[PrimaryExpr] = variableReference | `(` ~> expr <~ `)` ^^ { GroupedExpr } | functionCall | number | literal
å¯äžã®æ¡ä»¶ã¯ãæããå³å¯ãªãããŒãµãŒãã|ããä»ããŠãŠããªã³ã«å
¥ãããšãä¿èšŒããå¿
èŠãããããšã§ãã æ®ãã®åã«ã ãã®äŸã§ã¯ã颿°ã®ååã®è§£æã«æåããã ãã§ãfunctionCallãæåããå Žåã«ãªãã©ã«ãæããã«æåããŸãããããã£ãŠããªãã©ã«ãå
ã«é
眮ãããšãåã«functionCallã«å°éããŸããã
ããŒãµãŒã®ã»ããå
šäœã150è¡ã«åãŸãããªããžã§ã¯ãã¢ãã«ã®å®çŸ©ããã倧å¹
ã«çããªããŸãã
ããã¯ã¹å€æ°
åŒã«å€æ°ã远å ããã«ã¯ãããŒãžã§ã³2.10ã§ç»å Žããæååè£éã¡ã«ããºã ã䜿çšããŸãã
ã¡ã«ããºã ã¯éåžžã«ç°¡åã§ããæå¹ãªã¡ãœããåã§ããåã®è¡ïŒã¹ããŒã¹ãªãïŒã«ééãããšãã³ã³ãã€ã©ã¯åçŽãªå€æãå®è¡ããŸãã
t"strinf $x interpolation ${ obj.name.toString } " StringContext("strinf ", " interpolation ", " ").t(x, { obj.name.toString })
æååã¯ã倿°ãšåŒã®åºçŸã«ãã£ãŠæçã«åå²ãããStringContextãã¡ã¯ããªã¡ãœããã«æž¡ãããŸãã æååã®åã®ååã¯ã¡ãœããã®ååãšããŠäœ¿çšããããã¹ãŠã®å€æ°ãšåŒã¯ãã©ã¡ãŒã¿ãŒãšããŠãã®ã¡ââãœããã«æž¡ãããŸãã
ããããsãããfããªã©ã®ã¡ãœããã§çµããå ŽåãStringContextã«ãªãã¡ãœããã«ã€ããŠãã³ã³ãã€ã©ã¯æé»çãªã¯ã©ã¹ãã€ãŸãç®çã®ã¡ãœãããå«ãStringContextã®ã©ãããŒãæ¢ããŸãã ãã®ãããªæ€çŽ¢ã¯scalaã®äžè¬çãªã¡ã«ããºã ã§ãããæååè£éã«ã¯çŽæ¥é©çšãããŸããã
æçµã³ãŒãïŒ
new MyStringContextHelper(StringContext("strinf ", " interpolation ", " ")).t(x, { obj.name.toString })
ããããããŒãµãŒã¯ã©ãã§ããïŒ é£ç¶ããæååã¯ãªããªããŸããã ãããŠãæåã®ã·ãŒã±ã³ã¹ãšäœãä»ã®ãã®ããããŸãã
ãã¹ãŠã®äœæ¥ã¯ææ°ŽãããŠããŸããïŒ
ããã¯ãæåã®ã·ãŒã±ã³ã¹ã ãã§ãªãè§£æããæ©èœã®æçšæ§ãæããã«ãªãå Žæã§ãã
äžé£ã®æåãšä»ã®ãã®ããããŸãïŒããã«ã€ããŠã¯åŸã§èª¬æããŸãïŒã ããã¯ãã©ã¡ããã®æŠå¿µã§èª¬æãããŠããŸãã ããã«ã¯ãã·ã°ã«ã©ãã®ãããã
ã«é¢ãã ããã€ãã® èšäºã翻蚳ãããŠã
ãŸã ã
ããŒãµãŒã®èœåãæå€§éã«æŽ»çšããã«ã¯ãããã€ãã®è£å©ããŒã«ãäœæããã ãã§ãã ç¹ã«ãCharãStringãRegexãã察å¿ããããŒãµãŒãžã®å€æã
å¿
èŠãªãã¹ãŠã®ããŒã«ã¯æ¬¡ã®
ãšããã§ãïŒ
BothParsers ã æœè±¡åRã«æ³šæãæã䟡å€ããããŸããããã«ã€ããŠã¯æ³å®ãããŠããªãããããã®ããŒã«ãããã¯å€æ°ã衚ãããã®ä»¥åã¯æªç¥ã®æ¹æ³ã«é©ããŠããŸãã
ç·šéã«å¹²æžãã
ç§ã®æèŠã§ã¯ããã¯ãã«é¢ããããã¥ã¡ã³ããšåŠ¥åœãªäŸã¯ã»ãšãã©ãããŸããã ããããã ãããšãã£ãŠããã¯ããšã¯äœãããŸããã¯ããäœãé£ã¹ãã®ããç¶²çŸ
çã«èª¬æããã€ããã¯ãããŸããã
ãŸãããã¯ãããŒã¯ãŒãã䜿çšããŠå®è£
ãããã¡ãœãããã³ã³ãã€ã©ãæ€åºãããšãã«ãã¯ããåŒã³åºããããã¯ãå®è£
ãæ°ããäœæãããæ§æããªãŒãè¿ãå¿
èŠãããããšãç¥ã£ãŠããå¿
èŠããããŸãã
æãåçŽãªäŸã®ããã«ã©ã®ãããªããªãŒãäžããã¹ããèŠãŠã¿ãŸãããïŒ
scala> import scala.reflect.runtime.universe._ import scala.reflect.runtime.universe._ scala> showRaw(reify( "str" -> 'symb )) res0: String = Expr(Apply(Select(Apply(Select(Ident(scala.Predef), newTermName("any2ArrowAssoc")), List(Literal(Constant("str")))), newTermName("$minus$greater")), List(Apply(Select(Ident(scala.Symbol), newTermName("apply")), List(Literal(Constant("symb")))))))
ãã®ãããªèªåãæ§ç¯ããã«ã¯ãããããªæ¬²æ±ã¯ãããŸããã
scalaãæäœæ¥ãªãã§ã¿ã€ãã³ã°ãä¿åã§ããããšãèŠãŠã¿ãŸãããã
äžæ¹ã§ãå€ãã§ã¯ãããŸããïŒãªãã©ã«ã¡ãœãããããã¯ãããã€ãã®éããããåºæ¬åãã®ã»ãããæ§æããªãŒã«å€æãããã¹ãŠã®æåäœæ¥ãè¡ãreifyãå¯èœã«ããŸãããåãããªãŒã®åœ¢åŒã§å€éšãã倿°ã远å ããå Žåã®ã¿æ¬¡ã«ããã®ããªãŒã®spliceã¡ãœããã䜿çšããŸãããã®ã¡ãœããã¯ãçµæã®ã¿ã€ãTãæã€æ°ããããªãŒã®äžéšãšããŠãã¿ã€ãExpt [T]ã®åŒãåã蟌ããšããèŠæãå
·äœçã«éç¥ããããã«èšèšãããŠããŸãã
äžæ¹ããããã®æ¹æ³ã§ååã§ãã 远å ã¯å©çšå¯èœãªãã®ã«åºã¥ããŠæžãããšãã§ããŸãã
ãã¯ãèªäœã«ãã£ãŠåŠçããã
è£éã远å
ããããšã¯éåžžã«ç°¡æœã§ãã
implicit class XPathContext(sc: StringContext) { def xp(as: Any*): LocationPath = macro xpathImpl }
ãã¯ãåŠç颿°ã¯æ¬¡ã®ããã«å®£èšãããŸãã
def xpathImpl(c: Context)(as: c.Expr[Any]*): c.Expr[LocationPath]
ã©ããã倿°ãååŸãããã¯æç¢ºã§ãããæååãååŸããæ¹æ³ã¯ïŒ
ãããè¡ãã«ã¯ãã³ã³ããã¹ãã䜿çšããŠé¢æ°ããèŠããããšãã§ããŸãã ã€ãŸããåšããèŠãŠãã ããã
ããæ£ç¢ºã«ã¯ãã¿ãŒã²ããXPã¡ãœãããåŒã³åºãããåŒãèŠãŠãã ããã
ããã¯c.prefixã䜿çšããŠå®è¡ã§ããŸãã
ããããããã«ã¯äœãèŠã€ãããŸããïŒ StringContextïŒ "strinf"ã "interpolation"ã ""ïŒã®åœ¢åŒã®åŒãå¿
èŠã§ããããšã以åã«è¿°ã¹ãããŸããã
察å¿ããããªãŒãèŠãŠã¿ãŸãããïŒ
scala> import scala.reflect.runtime.universe._ import scala.reflect.runtime.universe._ scala> showRaw(reify(StringContext("strinf ", " interpolation ", " "))) res0: String = Expr(Apply(Select(Ident(scala.StringContext), newTermName("apply")), List(Literal(Constant("strinf ")), Literal(Constant(" interpolation ")), Literal(Constant(" ")))))
ãããããããããã«ããã¹ãŠã®è¡ãæç€ºçãªåœ¢åŒã§ååŸã§ããŸãã
val strings = c.prefix.tree match { case Apply(_, List(Apply(_, ss))) => ss case _ => c.abort(c.enclosingPosition, "not a interpolation of XPath. Cannot extract parts.") } val chars = strings.map{ case c.universe.Literal(Constant(source: String)) => source.map{ Left(_) } case _ => c.abort(c.enclosingPosition, "not a interpolation of XPath. Cannot extract string.") }
ããããå
¥ãå£ã ããå€ãã£ãããã§ã¯ãããŸããã ããŒãµãŒã®çµæã¯ãªããžã§ã¯ãã¢ãã«ã®ãªããžã§ã¯ãã§ã¯ãªããªããŸããå€ã§ã¯ãªãc.Expr [Any]ã®åœ¢åŒã®ãã©ã¡ãŒã¿ãŒã«åºã¥ããŠæ§ç¯ããããšã¯ã§ããŸããã
ããã«å¿ããŠããŒãµãŒã倿ŽããŸãã ãã®çµæãå€éšå€æ°ãå°ãªããšãäœããã®åœ¢ã§åºçŸããå¯èœæ§ãããå ŽåãããŒãµãŒã¯Tãè¿ãããšã¯ã§ããŸããããc.Expr [T]ãè¿ãå¿
èŠããããŸãã éåºæ¬åãã察å¿ããExprãžã®å€æã®ããã«ã䜿çšå¯èœãªãã®ã«åºã¥ããŠ
è£å©ãªãã©ã«
ã¡ãœãããäœæããŸããæ¬¡ã«äŸã瀺ããŸãã
def literal(name: QName): lc.Expr[QName] = reify{ QName(literal(name.prefix).splice, literal(name.localPart).splice) }
ãã®ãããªãã¹ãŠã®é¢æ°ã®åçã¯éåžžã«åçŽã§ããåŒæ°ãããªãåºæ¬çãªéšåã«è§£æããreifyå
ã§åæ§æããŸãã
ããã«ã¯æ©æ¢°çãªäœæ¥ãå¿
èŠã§ãããããŒãµãŒã¯ããã»ã©å€ãããŸããã
æåŸã®ã¹ãããã¯ãå
¥åã§å€æ°ãè§£æã§ããããã€ãã®ããŒãµãŒã®å°å
¥ã§ãã
以äžã¯ã倿°ãåã蟌ãããã®
ããŒãµãŒã§ãã
accept("xc.Expr[Any]", { case Right(e) => e } ) ^? ({ case e: xc.Expr[BigInt] if confirmType(e, tagOfBigInt.tpe) => reify{ CustomIntVariableExpr(VariableReference(QName(None, NCName(xc.literal(nextVarName).splice))), e.splice) } case e: xc.Expr[Double] if confirmType(e, xc.universe.definitions.DoubleClass.toType) => reify{ CustomDoubleVariableExpr(VariableReference(QName(None, NCName(xc.literal(nextVarName).splice))), e.splice) } case e: xc.Expr[String] if confirmType(e, xc.universe.definitions.StringClass.toType) => reify{ CustomStringVariableExpr(VariableReference(QName(None, NCName(xc.literal(nextVarName).splice))), e.splice) } }, e => s"Int, Long, BigInt, Double or String expression expected, $e found." )
æåã®ããŒãµãŒ "acceptïŒ" xc.Expr [Any] "ã{case RightïŒeïŒ=> e}ïŒ"ã¯éåžžã«åçŽã§ã-ããªãŒãæã€Rightã³ã³ãããåãå
¥ãããã®ããªãŒãè¿ããŸãã
ããã«å€æãè¡ããšããã®å€æ°ã3ã€ã®ç®çã®åã®ãããããšããŠäœ¿çšã§ãããã©ããã倿ããããã®ãããªäœ¿çšã«å€æãããŸãã
ãã®çµæã次ã®åäœãçºçããŸãã
scala> val xml = <book attr="111"/> xml: scala.xml.Elem = <book attr="111"/> scala> val os = Option("111") os: Option[String] = Some(111) scala> xml \\ xp"*[@attr = $os]"
ãŸãããšã©ãŒã¡ãã»ãŒãžãããã«æ¹åããå¿
èŠãããå Žåã倿°ã¯æ¢ã«éåžžã«äŸ¿å©ã«çµã¿èŸŒãŸããŠããŸãã
颿°ãåã蟌ãã«ã¯å€ãã®ã³ãŒãïŒ23ã®ãªãã·ã§ã³ã0ãã22ã®ãã©ã¡ãŒã¿ãŒã®ãªãã·ã§ã³çšïŒãå¿
èŠã§ãããAnyã®ã¿ãåãå
¥ããå¿
èŠããããããããŸã䟿å©ã§ã¯ãããŸããããåºæ¬çã«NodeListãæ¥ãŸãïŒãã ããè¡ãæ¥ãããDoubleã«ãªãå¯èœæ§ããããŸãïŒïŒ
scala> import org.w3c.dom.NodeList import org.w3c.dom.NodeList scala> val isAllowedAttributeOrText = (_: Any, _: Any) match {
ããã§ã¯ãXPathæ§æããæåã®æ··ä¹±ãååŸããŸããïŒå€æ°ã®ä»£ããã«$ {ä»»æã®ã³ãŒã}ã®åœ¢åŒã®åŒãèšè¿°ããå¯èœæ§ãé€ãïŒ-å®è£
ããã颿°ã®åã«ãã«ãä»ããå¿
èŠããããŸãã
ã¡ãœããã®å®è£
åœç¶ãscala.xml.NodeSeqã®ã¡ãœããã\ããšã\\ãèªäœã¯éæ³ã«ãã£ãŠçŸããã®ã§ã¯ãªã
ãã¢ãã«ã®
ããã±ãŒãžãªããžã§ã¯ãã®æé»ã¯ã©ã¹ã䜿çšããŠè¿œå ãã
ãŸã ã
åæ§ã®ã¡ãœããã
org.w3c.dom.Nodeããã³
NodeListã«çµã¿èŸŒãŸããŠã
ãŸã ã
ãŸããçµæã®XPathãé©çšãããšãç¹å®ã®åé¡ãçºçããŸãã
æªè§£æ±ºã®åé¡
java.lang.System.setSecurityManagerïŒnullïŒ
ãåãé€ããŸãã com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImplã®å®è£
ãã倿ãããšãã«ã¹ã¿ã 颿°ãã³ãã©ãŒã远å ããä»ã®æ¹æ³ã¯ãããŸããã
ã³ã³ãã€ã«æ®µéã§ã®ãšã©ãŒã¯æ¹åãå¿
èŠã§ãã
颿°ãæ£ããæå®ãããŠããªãå Žåããšã©ãŒã¡ãã»ãŒãžã¯å®ç§ã§ãïŒã³ã³ãã€ã©ã®åŠ¥åœæ§ã«å¯Ÿããå¥ã®è³èŸïŒïŒ
scala> xml \\ xp"*[$isAllowedAttributeOrText(@attr)]" <console>:1: error: type mismatch; found : (Any, Any) => Boolean required: Any => Any xml \\ xp"*[$isAllowedAttributeOrText(@attr)]" ^
ãã®åŸãä»ã®ãã¹ãŠã®ãšã©ãŒã«ã€ããŠã¯ãæšæºã®ã¡ãã»ãŒãžåœ¢åŒã¯å°éããããäœçœ®ã¯è¡ã®å§ãŸãã瀺ããŸãã
åã®åé¡ãšã¯ç°ãªãããã®åé¡ã¯å®å
šã«è§£æ±ºã§ããŸãã
scala.xmlã䜿çšãããšãã®ããã©ãŒãã³ã¹ã«ã¯ãå€ãã®èŠæããããŸãã å®éãscala.xmlããw3c.domãžã®å€æã¯ãæåã«æååãä»ããŠè¡ãããæ¬¡ã«éã«è¡ãããŸãã
å¯äžå¯èœãªè§£æ±ºçã¯ãXPathãèªåã§åŠçããããšã§ãã
åæã«ãããã¯ããŸã䟿å©ã§ã¯ãªã颿°ã®ã¿ã€ãã³ã°ãåãé€ããŸãã
w3c.domã®ããã©ãŒãã³ã¹ã¯ãããã«æ¹åã§ããŸãã XPathã¯çŸåšãæååããã³ã³ãã€ã«ãããŠããŸãããæ¢è£œã®ãªããžã§ã¯ãã¢ãã«ããããŸãã ãªããžã§ã¯ãã¢ãã«éã§å€æãããšãXPathã®äœæãå€å°éããªããŸãã
ãããã«
XPathã¯æ·±å»ãªåé¡ãå¶éãªãã«scalaã«çµ±åã§ããŸãã
çŸåšã®ã¹ã³ãŒãã®å€æ°ãšé¢æ°ã¯ã仿§ã§èš±å¯ãããŠããéãæå¹ã§ãã
w3c.domã§äœ¿çšããããã€ãã®æ¹åãå ããå Žåãã³ã³ãã€ã«äžã«åŒãè§£æãããããããããªå éãå¯èœã§ãã
ãã¹ãŠãã¯ããã«ç°¡åã§ãã äžèŠãããšæãããŸãã
æåã¯ãã³ã³ãã€ã«ã«åã蟌ããšããã¢ã€ãã¢èªäœãå°çãåŒãèµ·ãããŸãã çµæã¯æå°éã®åŽåã§éæãããŸãã
ã¯ããã³ã³ãã€ã©APIã¯ã¡ã€ã³ã©ã€ãã©ãªãããã¯ããã«æªãããã¥ã¡ã³ãã§ãããè«ççã§çè§£ããããã§ãã
ã¯ããIDEAã¯ãã¹äŸååãããçè§£ããŠããŸããããã³ã³ãã€ã©APIãå«ãéåžžã«äŸ¿å©ãªããã²ãŒã·ã§ã³ãæäŸããæé»çãªå€æãèæ
®ããŸãã