2015-08-20 25 views
1

Я только начал программировать в Scala и я столкнулся с трудностями с этой самой базовой структуры XML:Scala: Как добавить новый узел в файл XML и как удалить узел из XML-файл

<Countries> 

    <Country> 
     <Name>Italy</Name> 
     <Continent>Europe</Continent> 
    </Country> 

    <Country> 
     <Name>Japan</Name> 
     <Continent>Asia</Continent> 
    </Country> 

</Countries> 

Проблема 1: Я хотел бы добавить новый файл (новую страну) в файл. Я успешно загрузил файл, используя XML.loadFile, но не знаю, как добавить новый узел, а затем сохранить обратно файл.

Проблема 2: Я также хотел бы удалить узлы из файла, но даже здесь я затрудняюсь для достижения того, что хочу, особенно потому, что хочу удалить узел, в котором элемент соответствует названию страны, введенному пользователем.

Я использовал кусок кода, который я нашел в Интернете:

val removeIt = new RewriteRule { 
    override def transform(n: Node): NodeSeq = n match { 
     case e: Elem if (e \ "Name").text == "Japan" => NodeSeq.Empty 
     case n => n 
    } 
} 

Это работает, но, к сожалению, она возвращается обратно NodeSeq, что не принято в качестве параметра Xml.Save, а также я понятия не имею, как пройти параметр String, чтобы определить, какой узел удалить.

ответ

3

Предполагая, что я поместил ваш образец XML-кода в Country.xml.

<Countries> 
<Country> 
    <Name>Italy</Name> 
    <Continent>Europe</Continent> 
</Country> 

<Country> 
    <Name>Japan</Name> 
    <Continent>Asia</Continent> 
</Country> 
</Countries> 

Ниже Как я пытаюсь сделать это

object XMLLoader extends App { 

    def toBeAddedEntry(name: String, continent: String) = 
     <Country> 
      <Name>{ name }</Name> 
      <Continent>{ continent }</Continent> 
     </Country> 

    // For problem 1 How to add a new Node 
    def addNewEntry(originalXML: Elem, name: String, continent: String) = { 
     originalXML match { 
      case <Countries>{ innerProps @ _* }</Countries> => { 
       <Countries> { 
        innerProps ++ toBeAddedEntry(name, continent) 
       }</Countries> 
      } 
      case other => other 
     } 
    } 

    // For problem 2 How to delete node with element Name with certain value 
    def deleteEntry(originalXML: Elem, nameValue: String) = { 
     originalXML match { 
      /* 
       Considering you just start coding in Scala, the following explanation may help: 
       Here Elem is used as Extractor, actually the unapplySeq in Elem object is invoked 
       def unapplySeq(n: Node) = n match { 
        case _: SpecialNode | _: Group => None 
        case _ => Some((n.prefix, n.label, n.attributes, n.scope, n.child)) 
       } 
       Then we use sequence pattern(match against a sequence without specifying how long it can be) to 
       extract child of originalXML and do the filtering job 
      */ 

      case e @ Elem(_, _, _, _, countries @ _*) => { 
       /* 
        original is kind of like 
         <Country> 
          <Name>Japan</Name> 
          <Continent>Asia</Continent> 
         </Country> 
       */ 
       val changedNodes = countries filter { country => 
        (original \ "Name").exists(elem => elem.text != nameValue) 
       } 
       e.copy(child = changedNodes) 
      } 
      case _ => originalXML 
     } 
    } 

    // define your own way to load Country.xml 
    val originalXML = XML.load(getClass.getClassLoader.getResourceAsStream("Country.xml")) 
    val printer = new scala.xml.PrettyPrinter(80,5) 
    println(printer.format(addNewEntry(originalXML, "China", "Asia"))) 
    println(printer.format(deleteEntry(originalXML, "Japan"))) 
} 

Результат выглядит следующим образом:

<Countries> 
<Country> 
     <Name>Italy</Name> 
     <Continent>Europe</Continent> 
</Country> 
<Country> 
     <Name>Japan</Name> 
     <Continent>Asia</Continent> 
</Country> 
<Country> 
     <Name>China</Name> 
     <Continent>Asia</Continent> 
</Country> 
</Countries> 


<Countries> 
<Country> 
     <Name>Italy</Name> 
     <Continent>Europe</Continent> 
</Country> 
</Countries> 

Оставшуюся часть о написании узла обратно Country.xml , В любом случае, надеюсь, что это поможет.

+0

Все отлично, спасибо большое - на всякий случай вы хотите объяснить некоторые из таких логик, как эта строка, я бы очень признателен: Elem (_, _, _, _ и т. Д. – WPRookie82

Смежные вопросы