2013-07-18 10 views
0

使用Scala的,我有這樣的代碼:斯卡拉XML - 傳承使用.MAP法值XML

def insertRefIntoXml(ref: Int, entry: Node): Node = entry match { 
    case <root>{ mainRoot @ _* }</root> 
     => <root>{ mainRoot.map(insertRefIntoXml ref )}</root> 
    case <here>{ contents }</here> => <here>{ ref }</here> 
    case other @ _ => other 

}

我想要做的是繼續傳遞「裁判」值,直到我到達here元素,然後將其交換。

這不起作用。會怎樣?

檢查this link爲始發問題

+0

你可以顯示之前的XML和所需的XML之後? – cmbaxter

+0

@cmbaxter添加了一個指向我想要做的事情的前一個問題的鏈接 – bharal

回答

0

看看這對你的作品:

object TestXml { 
    def main(args: Array[String]) { 
    val xml = 
     <root>   
    <here> 
     <dealID>foo</dealID> 
    </here>   
    </root> 

    println(insertRefIntoXml(2, xml)) 
    } 

    def insertRefIntoXml(ref: Int, entry: Node): Node = {  
    def doInsertRef(n:Node):Node = {  
     n match { 
     case <root>{ mainRoot @ _* }</root> => <root>{ mainRoot.map(doInsertRef)}</root> 
     case <here><dealID>{ contents }</dealID></here> => <here><dealID>{ ref }</dealID></here> 
     case other @ _ => other 
     }  
    } 
    doInsertRef(scala.xml.Utility.trim(entry)) 
    } 
} 

有一對夫婦的問題。首先,爲了以您想要的方式在撥打map時使用insertRefIntoXml,它只需要一個參數,而不是兩個參數。爲了解決這個問題,我創建了一個局部函數def,然後通過閉包從ref中獲取值。你也可以解決這個問題是這樣,而不是:

def insertRefIntoXml(ref: Int, entry: Node): Node = {  
    entry match { 
     case <root>{ mainRoot @ _* }</root> => <root>{ mainRoot.map(insertRefIntoXml(ref, _))}</root> 
     case <here><dealID>{ contents }</dealID></here> => <here><dealID>{ ref }</dealID></here> 
     case other @ _ => other 
    }  
    } 

然後調用它像這樣:

insertRefIntoXml(2, scala.xml.Utility.trim(xml)) 

這使我想到第二個問題。我正在修整,以便匹配語句正確匹配。當我運行代碼時,我相信它會提供你想要的輸出。

0

該解決方案將是xml樹上的zipper結構。

使用的Anti-XML項目有,但它似乎已經落後,因此只船舶斯卡拉2.9.1

反正這是它如何工作,以防萬一,你會看的解決方案來獲得一些靈感

object XMLTreeUpdate { 
    import com.codecommit.antixml._ 
    import com.codecommit.antixml.Converter 

    def insertRefIntoXml(ref: Int, entry: Node, selector: String): Node = { 
    /* selects the node of interest, but with the 
    * structure around it to rebuild the original tree (this is a zipper) 
    */ 
    val zipper = Group(entry) \\ selector 

    //gets the zipper value and creates a modified copy 
    val mod = zipper.head.copy(children = Group(Text(ref.toString))) 

    /* updates the modified branch in the zipper and unwinds it 
    * then removes the zipper structure and gets the actual result 
    */ 
    zipper.updated(0, mod).unselect.stripZipper.head 
    } 

    def testIt = { 
    val entry = 
     <some> 
     <inner> 
      this is some content <here>n.d.</here> 
      but not <special>here</special> 
     </inner> 
     </some> 

    //converts to antixml node, which has a parallel api to scala.xml 
    val antry = entry.convert 

    val expected = 
     <some> 
     <inner> 
      this is some content <here>10</here> 
      but not <special>here</special> 
     </inner> 
     </some> 

    val output = insertRefIntoXml(10, antry, "here") 
    assert(expected.convert == output) 
    output 
    } 
}