我有一個格式化爲JSON的配置文件,我需要加載到Perl中,然後用從單獨的JSON文件加載的新設置部分覆蓋/擴展。可能會添加/更改的特定設置各不相同,因此我希望儘可能使這種覆蓋靈活。如何在Perl中合併兩個複雜的數據結構?
我的計劃是將一個新的部分配置合併到現有的完整配置對象中 - 無論是JSON還是使用decode_json後的Perl嵌套數據結構。該轉換工作正常。
有沒有一種簡單而有效的方法可以在Perl中完成此任務,而不是遞歸地遍歷我的複雜數據結構並進行大量特定的比較?我研究過Hash :: Merge,它正在修改我的數據。這個問題似乎是它會查看高級別的鍵/值對(下面的「config」或「bookToolbar」),並覆蓋該級別的完整鍵/值對。我想要的是先搜索深度優先,並覆蓋它可以的最具體的值,同時保持原始的其他鍵/值對。
例如,這裏是一個「完整」的配置:
{
"config" : {
"bookToolbar" : {
"highlights" : {
"enabled" : false
},
"bookmark" : {
"enabled" : false
}
},
"pageAspectRatio" : {
"width" : "432",
"height" : "648"
},
"highlighter" : {
"sharedColor" : "#000000",
"colors" : [
"#ffff00"
]
}
"mainMenu" : {
"index" : {
"dataPath" : "data/index/",
"enabled" : false
},
"media" : {
"dataPath" : "data/media.xml",
"enabled" : false
},
"toc" : {
"dataPath" : "data/toc.xml"
},
"glossary" : {
"audioPath" : "audio/glossary/",
"dataPath" : "data/glossary.xml",
"imagePath" : "img/glossary/",
"enabled" : false
}
}
},
"pagelist" : [{
"hasOnPageNotes" : true,
"pageName" : "cover",
"hasScreenReader" : false,
"hasTextMarkup" : true,
"hasLinks" : false,
"pageId" : "cover"
}, {
"hasOnPageNotes" : true,
"pageName" : "1",
"hasScreenReader" : false,
"hasTextMarkup" : true,
"hasLinks" : false,
"pageId" : "1"
}
]
}
,這裏是我想用,以部分地覆蓋數據/延伸以上:
{
"config" : {
"bookToolbar" : {
"bookmark" : {
"enabled" : true
},
"help" : {
"data" : {
"url" : "aGreatHelpFile.html"
},
"enabled" : true
},
"links" : {
"enabled" : true
}
}
},
"pagelist" : [{
"hasOnPageNotes" : true,
"pageName" : "2",
"hasScreenReader" : false,
"hasTextMarkup" : true,
"hasLinks" : false,
"pageId" : "2"
}
]
}
我的期望的輸出將是:
{
"config" : {
"bookToolbar" : {
"highlights" : {
"enabled" : false
},
"help" : {
"data" : {
"url" : "aGreatHelpFile.html"
},
"enabled" : true
},
"bookmark" : {
"enabled" : true
}
"links" : {
"enabled" : false
}
},
"pageAspectRatio" : {
"width" : "432",
"height" : "648"
},
"highlighter" : {
"sharedColor" : "#000000",
"colors" : [
"#ffff00"
]
},
"mainMenu" : {
"index" : {
"dataPath" : "data/index/",
"enabled" : false
},
"media" : {
"dataPath" : "data/media.xml",
"enabled" : false
},
"toc" : {
"dataPath" : "data/toc.xml"
},
"glossary" : {
"audioPath" : "audio/glossary/",
"dataPath" : "data/glossary.xml",
"imagePath" : "img/glossary/",
"enabled" : false
}
}
},
"pagelist" : [{
"hasOnPageNotes" : true,
"pageName" : "cover",
"hasScreenReader" : false,
"hasTextMarkup" : true,
"hasLinks" : false,
"pageId" : "cover"
}, {
"hasOnPageNotes" : true,
"pageName" : "1",
"hasScreenReader" : false,
"hasTextMarkup" : true,
"hasLinks" : false,
"pageId" : "1"
}, {
"hasOnPageNotes" : true,
"pageName" : "2",
"hasScreenReader" : false,
"hasTextMarkup" : true,
"hasLinks" : false,
"pageId" : "2"
}
]
}
我與'RIGHT_PRECEDENT'合併和似乎得到你想要的結果哈希::合併的文檔中提到下的ActiveState Perl的Windows上運行的一些問題,或與舊版本的。克隆模塊。Coul這些都是你的問題嗎? – rutter
嗯,我試過RIGHT_PRECEDENT沒有運氣,但它聽起來像只是想要我想要的。我確實在Windows上使用ActiveState distrib,所以這可能是問題...讓我在我的Mac上嘗試它,看看它是否有所改善。 – uptownnickbrown
因此,使用'Hash :: Merge'和'RIGHT_PRECEDENT'確實可以在我的Mac上完美工作......並且在將Clone更新到最新版本之後([Clone-0.34](http://search.cpan.org/~rdf/ Clone-0.23/Clone.pm))它也適用於Windows!感謝提示重新訪問該行爲選項。 – uptownnickbrown