Programming in Scala Notes-Chapter 28th, XML-related __scala

Source: Internet
Author: User
Tags serialization string format

This chapter describes Scala's support for XML, including the main contents of this article at the level of headings.

A description of the concept and XML format of semi-structured data is skipped, directly into Scala's XML-related syntax and usage. First, XML syntax

The Scala command line can be entered directly at the beginning of a tag, and the compiler automatically enters the XML input pattern until it encounters a closing flag that matches the tag. As shown below:

scala> <a>
     |   This is some XML.
     |   Here's a tag: <atag/>
     | </a>
Res25:scala.xml.Elem =
<a> This is
  some XML.
  Here is a tag: <atag/>
</a>

The above code gets an object of type Scala.xml.Elem. In Scala, other XML-related classes also include:
Node XML parent of all node classes
Text a node that contains only XML values. For example, the stuff part of <a>stuff</a>.
NODESEQ node sequence

In addition to entering the complete XML tags and values directly in the image above, you can dynamically compute the value part with {} in the value section. As shown in the following figure,

scala> <a> {"Hello" + ", World"} </a>
Res26:scala.xml.Elem = <a> Hello, world </a>

In the code above {} is a string concatenation expression, in {} can contain any form of Scala expression, such as if ... else ... And so on, you can also access variables defined in {}. Second, serialization

Serialization here refers to the conversion of an object into an XML form. Corresponds to the following deserialization.

The code shown below defines a cctherm abstract class.

Abstract class Cctherm {
  val description:string
  val yearmade:int
  val dateobtained:string
  val  Bookprice:int//In US cents
  Val purchaseprice:int//in US cents
  Val condition:int//1
  override Def toString = Description

  def toXML =
    <cctherm>
      <description>{description}</description >
      <yearMade>{yearMade}</yearMade>
      <dateobtained>{dateobtained}</dateobtained >
      <bookPrice>{bookPrice}</bookPrice>
      <purchaseprice>{purchaseprice}</ purchaseprice>
      <condition>{condition}</condition>
    </cctherm>
}

The ToXml method in the above code can be converted to a Scala.xml.Elem type variable based on the properties of the Cctherm class.

The following code constructs an object of type Cctherm and invokes the ToXml method to convert the class to XML.

Val therm = new Cctherm {
  val description = "Hot Dog #5"
  val yearmade = 1952
  val dateobtained = "March 14, 200 6 "
  val bookprice = 2199
  val purchaseprice =
  val condition = 9
}
println (therm)
println ( Therm.toxml)

The results are as follows:

Hot dog #5
<cctherm>
      <description>hot dog #5 </description>
      <yearmade>1952 </yearMade>
      <dateobtained>march, 2006</dateobtained>
      <bookprice>2199</ bookprice>
      <purchasePrice>500</purchasePrice>
      <condition>9</condition>
    </cctherm>

Finally, if you want to enter {or} in the content of the XML, you need to enter two at a time, as follows:

Scala> <a> {{{brace yourself!}}} </a>
Res27:scala.xml.Elem = <a> {brace yourself!}} </a >
third, XML data access

Of the multiple methods provided in the XML class, there are three methods that can be used to parse XML and get some of the information directly. 1, text method, get the value part of XML node

scala> <a>sounds <tag/> good</a>.text
res28:string = Sounds  Good
2, \ Methods and \ Methods to get the child elements in the XML

(1) \ Method

Scala> <a><b><c>hello</c></b></a> \ "B"
Res4:scala.xml.NodeSeq = NodeSeq (<b><c>hello</c></b>)

Scala> <a><b><c>hello</c></b></a> \ "C"
Res5:scala.xml.NodeSeq = NodeSeq ()

scala> <a><b><c>hello</c></b></a> \ "B" \ "C"
res6: Scala.xml.NodeSeq = NodeSeq (<c>hello</c>)

scala> <a><b><c>hello</c> </b></a>.text
res7:string = Hello

As you can see from the figure above, the \ method returns an object of type NodeSeq, even if the specified child element has only one.
As you can see in the figure above, the text method can also get the value part directly in the nested XML.

(2) \ \ Method
The above \ method can only get the next layer of child elements, for example, direct access to the child element "C", the resulting empty nodeseq. If you want to access the "C" element directly and get the corresponding child element, then you need to use the \ method.

Scala> <a><b><c>hello</c></b></a> \ "C"
Res8:scala.xml.NodeSeq = NodeSeq ()

scala> <a><b><c>hello</c></b></a> \ "C"
Res9:scala.xml.NodeSeq = NodeSeq (<c>hello</c>)

scala> <a><b><c>hello</c></b></a> \ "A"
Res10:scala.xml.NodeSeq = NodeSeq ()

scala> <a><b><c>hello</c></b> </a> \ "A"
Res11:scala.xml.NodeSeq = NodeSeq (<a><b><c>hello</c></b></a >)
3, @ method, get the property value of the label

In the XML tab, you can specify some label properties. Labels with no attributes, such as <A/>, with attributes such as <a name= "x" age= "/>". Use the @ method to get the value of the ' name ', ' Age ' section.
The @ symbol needs to be used in conjunction with the ' or \ \ method.

Scala> val joe = <employee
     | name= "Joe"
     | rank= "code Monkey"
     | serial= "123"/>
Joe: Scala.xml.Elem = <employee name= "Joe" rank= "code Monkey" serial= "123"/> scala>

Joe \ "@name"
res12: Scala.xml.NodeSeq = Joe

scala> joe \ "@serial"
res13:scala.xml.NodeSeq = 123

scala> joe \ "@x"
Res 14:scala.xml.nodeseq = NodeSeq ()

The method returns a variable of type NodeSeq. When you access a property that does not exist, you get an empty nodeseq. Iv. deserialization

Deserialization, in contrast to the serialization process described earlier, is a process used to convert an XML element into a generic object. Combining the three methods mentioned above, you can easily get the value of the specified element to convert the XML into a normal object.

Continue to add the FromXml method to the previous Cctherm class, as follows:

def fromxml (node:scala.xml.Node): Cctherm =
  new Cctherm {
    val description = (node \ "description"). Text
    Val y Earmade = (node \ "Yearmade"). Text.toint
    val dateobtained = (node \ "dateobtained"). Text
    val bookprice = (node \ " Bookprice "). Text.toint
    val purchaseprice = (node \ purchaseprice). text.toint
    val condition = (node \" Condition "). Text.toint
  }
v. Loading and saving

As you can see from the previous command-line pattern, the XML type's own ToString method can convert the contents of it to string.

However, it is best to use some of the methods provided by XML to manually convert the XML content into a string format for output. Because this output will contain some attributes, such as character encoding. 1, Scala.xml.XML.save method to save the XML content to the specified file

Use the following scala.xml.XML.save ("Therm1.xml", node). After execution, open Therm1.xml ', which reads as follows:

<?xml version= ' 1.0 ' encoding= ' UTF-8 '?>
<cctherm>
      <description>hot dog #5 </description >
      <yearMade>1952</yearMade>
      <dateobtained>march, 2006</dateobtained>
      <bookPrice>2199</bookPrice>
      <purchasePrice>500</purchasePrice>
      <condition >9</condition>
    </cctherm>
2, XML. Xml.loadfile method to load the XML file directly into the Scala.xml.Elem object

Val Loadnode = XML as shown below. Xml.loadfile ("Therm1.xml"), the results of the operation are as follows:

<cctherm>
      <description>hot Dog #5 </description>
      <yearMade>1952</yearMade>
      <dateobtained>march, 2006</dateobtained>
      <bookPrice>2199</bookPrice>
      <purchasePrice>500</purchasePrice>
      <condition>9</condition>
    </cctherm>
pattern matching in XML

So far, you've learned how to survive an XML type object and how to get the value of a specified element out of XML. But the methods described above are useful only if you know exactly what the XML file is, and you know what you're taking out of it. 1, pattern matching simple application

Pattern matching in XML is similar to XML expressions, except that the content in the XML expression {} is Scala code, but the content in the pattern match {} is a matching pattern.

Examples are as follows:

def proc (node:scala.xml.Node): String =
  node Match {case
  <a>{contents}</a> => "It's an A:" + cont Ents case
  <b>{contents}</b> => "It's a B:" + contents Case
  _ => "It s something else."
}

The results of the operation are as follows:

scala> proc (<a>apple</a>)
res15:string = It ' s an a:apple

scala> proc (<b>banana</b >)
res16:string = It ' s a b:banana

scala> proc (<c>cherry</c>)
res17:string = It ' s Somet Hing else.

However, the pattern matching above can only handle one layer of XML objects and cannot be resolved for nested XML as follows:

scala> proc (<a>a <em>red</em> apple</a>)
res18:string = It ' s something else.

scala> proc (<a/>)
res19:string = It ' s something else.
2, Pattern matching advanced application

We usually want the XML schema matching functionality to be more than simple, and it's best to match the nested XML elements. The XML node sequence is taken out of the nested XML. In pattern matching should be written in the form of _*.

The improved Proc method looks like this:

def proc (node:scala.xml.Node): String =
  node Match {case
  <a>{contents @ _*}</a> => "It's" an A: "+ Contents Case
  <b>{contents @ _*}</b> => "It's a B:" + contents Case
  _ => "It ' s something else."
}

There is a @ symbol in the code before _*, this is the variable binding mentioned in Scala pattern matching, by the @ symbol, you can bind the matching content to the contents variable, you can use the variable directly in the subsequent code.

The results of the operation are as follows

scala> proc (<a>a <em>red</em> apple</a>)
res20:string = It ' s an A:arraybuffer (A, <em >red</em>,  Apple)

scala> proc (<a/>)
res21:string = It ' s an A:wrappedarray ()

Pattern matching is a better way to parse XML, look at the following example:

Val Catalog =
<catalog>
  <cctherm>
    <description>hot dog #5 </description>
    <yearMade>1952</yearMade>
    <dateobtained>march, 2006</dateobtained>
    < bookprice>2199</bookprice>
    <purchasePrice>500</purchasePrice>
    <condition>9 </condition>
  </cctherm>
  <cctherm>
    <description>sprite boy</description >
    <yearMade>1964</yearMade>
    <dateobtained>april, 2003</dateobtained>
    <bookPrice>1695</bookPrice>
    <purchasePrice>595</purchasePrice>
    < condition>5</condition>
  </cctherm>
</catalog>

See from your code that there are two <cctherm> child elements under the <catalog> label. But the results are printed as follows. This is because after the label <catalog>, the content contained is its child element, we can see at the beginning and end of the most of the label there is a newline, and there are two <cctherm> between the existence of line breaks.

Scala> Catalog Match {
     |   Case <catalog>{therms @ _*}</catalog> =>
     |     For (therm <-therms)
     |       println ("Processing:" +
     |       (therm \ "description"). Text)
     |}
Processing: 
processing:hot dog #5
processing: 
processing:sprite Boy

You can see from the result that there is an empty element before and after each <catalog> label. You can skip these empty elements by using the following code to process the XML.

Scala> Catalog Match {
     |   Case <catalog>{therms @ _*}</catalog> =>
     |     for (therm @ <cctherm>{_*}</cctherm> <-therms)
     |       println ("Processing:" +
     |       (therm \ "description"). Text)
     |}
Processing:hot dog #5
processing:sprite Boy

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.