如何从Scala中调用Groovy脚本?附XML内嵌Groovy示例解析
Let's walk through how to extract and execute the Groovy script embedded in your XML file from Scala. We'll break this into two main parts: parsing the XML to get the script content, then running that script using Groovy's libraries.
Step 1: Extract the Groovy Script from XML
First, we need to pull the Groovy code out of the <script> tag's CDATA section. You mentioned a Java utility NREUtils.readXml that returns a List<Fact>—since Scala plays nice with Java, we can reuse that directly.
Assuming your Fact class has a method to retrieve the script (like getScript()), here's how to grab the relevant code:
import com.yourpackage.NREUtils import com.yourpackage.Fact import scala.jdk.CollectionConverters._ // Read XML into a list of Fact objects using your existing Java utility val factList: List[Fact] = NREUtils.readXml("path/to/your/facts.xml").asScala.toList // Find the "ItemPrice" fact and extract its script val itemPriceScript = factList .find(_.getId == "ItemPrice") .map(_.getScript) .getOrElse(throw new IllegalArgumentException("ItemPrice fact not found"))
If you prefer a pure Scala XML parsing approach (no Java utility required), use Scala's built-in XML handling:
import scala.xml.XML // Load the XML file val xml = XML.loadFile("path/to/your/facts.xml") // Extract the script text from the CDATA section val groovyScript = (xml \ "fact" \ "script").text.trim
Step 2: Execute the Groovy Script in Scala
To run the Groovy script, you'll need to add the Groovy library to your project. Update your build.sbt with this dependency:
libraryDependencies += "org.codehaus.groovy" % "groovy" % "3.0.17" // Use the latest stable version
Then use GroovyShell—the simplest way to execute Groovy code from Scala:
import groovy.lang.GroovyShell // Create a GroovyShell instance val shell = new GroovyShell() // Execute the script and cast the result to the expected type val calculatedPrice = shell.evaluate(groovyScript).asInstanceOf[Double] println(s"Calculated Item Price: $calculatedPrice") // Outputs 50.0 for your example
If you need to pass custom variables to the script (instead of hardcoding them inside the CDATA), use a Binding:
import groovy.lang.GroovyShell import groovy.lang.Binding // Define variables to pass to the script val binding = new Binding() binding.setVariable("Value_Sales", 750.0) binding.setVariable("Unit_Sales", 15.0) // Execute the script with the custom binding val shell = new GroovyShell(binding) val customPrice = shell.evaluate(groovyScript).asInstanceOf[Double] println(s"Custom Calculated Price: $customPrice") // Outputs 50.0 here too
Full Combined Example
Here's a complete Scala program that ties everything together:
import scala.xml.XML import groovy.lang.GroovyShell object GroovyScriptRunner extends App { // Extract script from XML val xml = XML.loadFile("path/to/your/facts.xml") val groovyScript = (xml \ "fact" \ "script").text.trim // Execute the script val shell = new GroovyShell() val itemPrice = shell.evaluate(groovyScript).asInstanceOf[Double] println(s"Final Item Price Result: $itemPrice") // Prints 50.0 }
Key Notes
- Always handle potential errors in production code (e.g., missing facts, script execution failures, type casting issues).
- Ensure your project's classpath includes the Groovy library—this is critical for the script execution to work.
- If you're using the Java
NREUtilsutility, make sure the Scala code has access to theFactclass and its methods.
内容的提问来源于stack exchange,提问作者Sujith AK

