【问题标题】:Java library function to turn arbitrary String into XML ID将任意字符串转换为 XML ID 的 Java 库函数
【发布时间】:2014-07-17 10:13:50
【问题描述】:

我认为这一定存在于某个地方,但很难搜索。

库可以是 JDK、Guava、Commons-lang、xml 处理库或任何相当知名的库。

行为可以是剥离或转义,但对于一堆唯一的、人类可读的、没有特殊字符的名称,转义结果也应该是唯一的并且是合理的人类可读的。

谢谢。

【问题讨论】:

标签: java xml escaping


【解决方案1】:

您很可能不想转义字符串(通常是可逆的),而是想“清理”字符串(仅保留其原始字符的子集,即那些安全的字符) ,可能无法恢复原始字符串)。正如您在 cmets 中提到的,ID 可能非常挑剔。

所以我们选择了一个安全范围并删除了该范围之外的任何内容。此外,如果它以非字母开头,我们会在前面加上“i”以使其符合要求。

public String toSafeId(String s) {
     s = s.replaceAll("[^a-zA-Z0-9]+", "-"); // replaces runs of non-valid by '-'
     return s.length() > 0 && Character.isLetter(s.charAt(0)) ? s : "i" + s;
}

请注意,这并不强制唯一性。要强制执行它,请用 Set 包装它:

public class XmlIdGenerator {
    private HashSet<String> used;

    // provides a unique ID
    public String generate(String s) {
        String base = toSafeId(s);
        String id = base;
        for (int i = 1; used.contains(id); i++) {
            id = base + "-" + i;
        }
        used.add(id);
        return id;
    }
}

用作:

XmlIdGenerator gen = new XmlIdGenerator(); // build a new one for each document
String oneId = gen.generate("   hi there sally!");      // -> "hi-there-sally"
String anotherId = gen.generate(" hi there.. sally?");  // -> "hi-there-sally-1"

【讨论】:

  • 谢谢,但我不确定这是否足够。上面 Aubin 评论中引用的 NCNAME 生产比 escapeXml 转义的要窄得多。例如,ID 的开头不能有数字。
  • True - 这只会转义字符。但是,您可以通过添加“i”前缀轻松保证特定部分。
  • 是的,但是像 ^ 这样的转义符号仍然不会使它们在 ID 中有效。它们要么必须被删除,要么以不同的方式转义。
  • 将我的方法从“尽可能少地更改字符串”更改为“比抱歉更安全”
  • 我不得不将return Character.isLetter(s.get(0) ? s : "i" + s; 更改为return Character.isLetter(s.charAt(0)) ? s : "i" + s;,因为缺少括号并且字符串上的get 方法未定义。
【解决方案2】:

有时我使用库 XStream,请查看此“2 分钟教程”

http://x-stream.github.io/tutorial.html


创建具有信息的对象

public class Person {
  private String firstname;
  private String lastname;
  private PhoneNumber phone;
  private PhoneNumber fax;
  // ... constructors and methods
}

public class PhoneNumber {
  private int code;
  private String number;
  // ... constructors and methods
}

启动 xtream

XStream xstream = new XStream();

将信息插入为别名

xstream.alias("person", Person.class);
xstream.alias("phonenumber", PhoneNumber.class);

插入信息

Person joe = new Person("Joe", "Walnes");
joe.setPhone(new PhoneNumber(123, "1234-456"));
joe.setFax(new PhoneNumber(123, "9999-999"));

生成 XML

String xml = xstream.toXML(joe);

【讨论】:

  • 添加具体代码sn -p - 只是链接到信息不被认为是一个好的答案。
  • 恢复了否定,但它对 ID 没有任何作用。问题是“如何将字符串转换为 ID”,而不是“如何以编程方式创建 XML 文档”
猜你喜欢
  • 1970-01-01
  • 2011-11-18
  • 2014-02-18
  • 1970-01-01
  • 2015-01-13
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多