A niechby to był taki malutki projekcik, jak ten mój, dzisiejszy do obrabiania XMLi. Nic nadzwyczajnego, ale czego oczekiwać od nowicjusza scalowego, który karierę w tym języku liczy w dniach (a nie tygodniach, czy miesiącach)?! Każdy przecież kiedyś był początkujący w rzeczach, w których teraz wiedzie prym. Ja właśnie zaczynam swoje pierwsze kroki w Scali i twory przypominają prawdziwe potwory, ale od czegoś zacząć należy!
Wierzę, że z pomocą Grześka, teamon'a oraz dmilith'a nauka Scali będzie tylko przyjemnością!
Pora na odsłonę mojego dzieła. Komentarze mile widziane.
package pl.japila.wli.transformations.control import scala.xml.{ XML, Node, Elem } import scala.xml.transform.{ RuleTransformer, RewriteRule } object WLIControlMigrationMain { // FIXME: Remove it once the script reads input args or we find them a better place val pkg = "pl.japila.wli.transformations.control".replace(".", "/") def main(args: Array[String]) { // The file comes from the BPEL Exporter in WLI val processCtrlXml = XML.load(getClass.getResourceAsStream(s"/${pkg}/process_ctrl.wsdl")) val portType = (processCtrlXml \ "portType" \ "@name").text // The file is ours - the template for a JMS import val importXmlTemplate = XML.load(getClass.getResourceAsStream(s"/${pkg}/import-xml.template")) // The file name and the name of the import component must be alike val importComponentName = portType + "_MB_Publish_control" println(s"+++\n+++ Save the following file as ${importComponentName}.import:\n+++") println(importXmlTemplate.toString .replace("{importComponentName}", importComponentName) .replace("{portType}", portType)) println(s"+++\n+++ Save the following file as process.component:\n+++") wireComponentWithImport(importComponentName) } def wireComponentWithImport(importComponentName: String) { val processComponentXML = XML.load(getClass.getResourceAsStream(s"/${pkg}/process.component")) val wire = XML.loadString(s"<wire target='${importComponentName}'/>") val wiredProcessComponentXML = new RuleTransformer( new AddChildrenTo("reference", wire)) .transform(processComponentXML).head println(wiredProcessComponentXML) } // http://stackoverflow.com/questions/2199040/scala-xml-building-adding-children-to-existing-nodes def addChild(n: Node, newChild: Node) = n match { case Elem(prefix, label, attribs, scope, child @ _*) => Elem(prefix, label, attribs, scope, child ++ newChild: _*) case _ => sys.error("Can only add children to elements!") } class AddChildrenTo(label: String, newChild: Node) extends RewriteRule { override def transform(n: Node) = n match { case Elem(_, `label`, _, _, _*) => addChild(n, newChild) case _ => n } } }
Gratuluję pierwszego projektu!
OdpowiedzUsuńKilka drobnych uwag:
W metodzie addChildrenTo możesz usunąć fragment "n @".
Możesz również zamienić case other => other na case _ => n (ale zapis z other może oczywiście zostać).
Zamiast XML.load i getResourceAsStream możesz użyć XML.loadFile i podać ścieżkę pliku po prostu.
Po toString nie potrzebujesz dodawać nawiasów ()
Dzięki Grzesiek.
UsuńOdnośnie zmian to:
-> n @ jest faktycznie nadmiarowe, bo skoro wpada w pierwszy case to już jest n-em. Skopiowałem z SO bez większego zastanowienia.
-> przyjmuję uwagę o case _. Zdaje się być idiomem, który przechwytuje wszystko pozostałe i taki jest właśnie zamiar tego wyrażenia.
-> XML.loadFile ładuje plik ze znanego miejsca w systemie plików. Na chwilę obecną odpada, bo nie obsługuję podawania plików z linii poleceń i pracuję wyłącznie z tymi, które znajdę na CLASSPATH. Stąd właśnie użycie XML.load(InputStream).
-> Z tymi nawiasami muszę sobie pożyć trochę, bo przy println ich nie chciałbym dawać, a muszą być, a w innych miejscach dodaję samoistnie.
Dzięki jeszcze raz za uwagi. Pomocne wielce!
p.s. Siedzę właśnie nad zipperami w Scali. Patrz http://en.wikipedia.org/wiki/Zipper_%28data_structure%29 oraz http://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf. Widziałem to pierwszy raz przy nauce Clojure i teraz pojawiło się ponownie przy tym zadaniu w Scali. To mogłoby być ciekawym tematem na szkolenie/warsztaty z zaawansowanej Scali.
Poprawione! Jeszcze raz dziękuję za uwagę i uwagi :-)
Usuń