如何用xml2强制格式化GeoServer的SLD文件为缩进换行格式?
解决xml2生成SLD文件时标签不缩进换行的问题
问题背景
用R的xml2包批量生成GeoServer的SLD(XML格式)文件时,小型测试示例能生成带缩进、每个标签单独一行的格式,但基于复杂SLD模板修改后,新增的标签会挤在同一行,不符合服务器管理员的格式要求。
解决方法
方法1:读取模板时忽略空白节点
读取SLD模板时,添加options = "noblanks"参数,让xml2忽略原文档中的空白文本节点,后续添加新节点后写入时会自动生成规范的缩进和换行:
library(xml2) # 读取模板时启用noblanks选项 xml_file <- read_xml('<?xml version="1.0" encoding="UTF-8"?> <sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" version="1.0.0"> <sld:NamedLayer> <sld:Name>SLD template for qualitative rasters</sld:Name> <sld:UserStyle> <sld:Name>SLD template for qualitative rasters</sld:Name> <sld:FeatureTypeStyle> <sld:Name>name</sld:Name> <sld:Rule> <sld:RasterSymbolizer> </sld:RasterSymbolizer> </sld:Rule> </sld:FeatureTypeStyle> </sld:UserStyle> </sld:NamedLayer> </sld:StyledLayerDescriptor>', options = "noblanks") # 执行节点修改操作(与原代码一致) namedlayer <- xml_find_first(xml_file, ".//sld:NamedLayer") namelayer <- xml_find_first(namedlayer, ".//sld:Name") xml_text(namelayer) <- "Name changed" userstyle <- xml_find_first(namedlayer, ".//sld:UserStyle") namelayer <- xml_find_first(userstyle, ".//sld:Name") xml_text(namelayer) <- "Name changed" symb <- xml_find_first(xml_file, ".//sld:RasterSymbolizer") xml_add_child(symb, "sld:ColorMap", type = "values", .where = 1) colormap <- xml_find_first(xml_file, ".//sld:ColorMap") labels <- letters[1:5] colors <- viridis::turbo(5) for (i in seq_along(labels)) { xml_add_child(colormap, "sld:ColorMapEntry", color = colors[[i]], quantity = i, label = labels[[i]], .where = i) } # 写入文件,显式开启格式化 write_xml(xml_file, "reprex.sld", format = TRUE)
方法2:修改后重新格式化文档
如果已经读取了文档,可在完成所有节点修改后,用xml_format()重新排版整个XML,再写入文件:
# 完成所有节点修改后执行 formatted_xml <- xml_format(xml_file, indent = 2) write_lines(formatted_xml, "reprex.sld")
indent参数可指定缩进的空格数,默认值为2,符合常规XML格式规范。
效果验证
使用上述方法后,生成的SLD文件会呈现规范的缩进和换行:
<?xml version="1.0" encoding="UTF-8"?> <sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" version="1.0.0"> <sld:NamedLayer> <sld:Name>Name changed</sld:Name> <sld:UserStyle> <sld:Name>Name changed</sld:Name> <sld:FeatureTypeStyle> <sld:Name>name</sld:Name> <sld:Rule> <sld:RasterSymbolizer> <sld:ColorMap type="values"> <sld:ColorMapEntry color="#30123BFF" quantity="1" label="a"/> <sld:ColorMapEntry color="#28BBECFF" quantity="2" label="b"/> <sld:ColorMapEntry color="#A2FC3CFF" quantity="3" label="c"/> <sld:ColorMapEntry color="#FB8022FF" quantity="4" label="d"/> <sld:ColorMapEntry color="#7A0403FF" quantity="5" label="e"/> </sld:ColorMap> </sld:RasterSymbolizer> </sld:Rule> </sld:FeatureTypeStyle> </sld:UserStyle> </sld:NamedLayer> </sld:StyledLayerDescriptor>
原理说明
xml2基于libxml2库,默认会保留原XML文档中的空白文本节点(如标签间的换行、空格)。当原模板中某个标签内部的空白节点未被规范处理时,新增子节点会直接追加到该标签内,无法自动生成换行缩进。通过noblanks选项移除空白节点,或用xml_format()重新排版,可强制生成统一的格式。
内容的提问来源于stack exchange,提问作者Josep Pueyo
相关产品推荐
相关产品推荐

