如何在Unicode XML字符数据库(UCD/UCDXML)中用XPath提取数值码点?
解决xmllint XPath查询Unicode UCD XML失效的问题
我一眼就看穿问题所在了——你的XML根节点带了默认命名空间xmlns="http://www.unicode.org/ns/2003/ucd/1.0",而xmllint默认使用的XPath 1.0不会自动识别默认命名空间。这就导致你直接用ucd/repertoire/char这种路径查询时,XPath会去找没有命名空间的节点,自然匹配不到实际属于Unicode命名空间下的那些节点。
下面给你两种可行的解决方案,任选其一就行:
方案1:用local-name()绕开命名空间查询
这种方式不需要额外配置,直接在XPath里通过节点的本地名称来匹配,同时筛选nv属性不等于NaN的char节点:
# 同时提取cp和nv属性 xmllint --xpath "//*[local-name()='ucd']/*[local-name()='repertoire']/*[local-name()='char'][@nv != 'NaN']/@cp | //*[local-name()='ucd']/*[local-name()='repertoire']/*[local-name()='char'][@nv != 'NaN']/@nv" your-ucd-file.xml
如果想一次性获取包含两个属性的完整char节点,方便后续处理,可以用这个:
xmllint --xpath "//*[local-name()='ucd']/*[local-name()='repertoire']/*[local-name()='char'][@nv != 'NaN']" your-ucd-file.xml
方案2:绑定命名空间前缀,让XPath更简洁
xmllint支持用-N参数给命名空间绑定一个前缀,这样写XPath会更直观:
# 先把Unicode命名空间绑定到ucd前缀,再查询 xmllint -N ucd=http://www.unicode.org/ns/2003/ucd/1.0 --xpath "//ucd:ucd/ucd:repertoire/ucd:char[@nv != 'NaN']/@cp | //ucd:ucd/ucd:repertoire/ucd:char[@nv != 'NaN']/@nv" your-ucd-file.xml
这里ucd:ucd对应根节点,ucd:char就是你要找的目标节点,[@nv != 'NaN']精准过滤掉nv为NaN的条目。
额外提示:生成C语言表格
拿到属性值后,你可以用awk之类的工具把输出转换成C表格格式。比如用awk处理属性输出,生成类似这样的代码:
xmllint [上面的查询命令] | awk -F'"' '{if (NR%2==1) cp=$2; else printf "{0x%s, %s},\n", cp, $2}'
这样就能直接得到可以插入C文件的表格片段了。
内容的提问来源于stack exchange,提问作者MarcusJ
相关产品推荐
相关产品推荐

