Java库函数,用于将任意字符串转换为XML ID

Java库函数,用于将任意字符串转换为XML ID,java,xml,escaping,Java,Xml,Escaping,我想这肯定存在于某个地方,但很难找到 该库可以是JDK、Guava、Commons lang、xml处理库或任何相当知名的库 该行为可以是剥离或转义,但对于一组唯一的、人类可读的名称(没有特殊字符),转义结果也应该是唯一的,并且合理地人类可读 谢谢。有时我使用XStream库,请查看“2分钟教程” 创建包含该信息的对象 public class Person { private String firstname; private String lastname; private

我想这肯定存在于某个地方,但很难找到

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

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


谢谢。

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


创建包含该信息的对象

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的Generete

String xml = xstream.toXML(joe);

您很可能不希望转义字符串(通常是可逆的),而是希望“清理”字符串(仅保留其原始字符的一部分,即安全的字符,可能导致无法恢复原始字符串)。正如您在评论中提到的,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;
}
请注意,这并不强制唯一性。若要强制执行,请将其包装为一组:

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;
    }
}

ID由另一个NCNAME定义添加特定代码段-仅链接到信息不被认为是一个好的答案。已还原为否定,但它对ID没有任何作用。问题是“如何将字符串转换为ID”,而不是“如何以编程方式创建XML文档”,谢谢,但我不确定这是否足够。上面奥宾评论中引用的
NCNAME
产品比
escapeXml
escape要窄得多。例如,ID的开头不能有数字。True-这仅转义字符。但是,您可以通过添加一个“i”前缀轻松地保证特定的部分。是的,但是像
^
这样的转义符号仍然不能使它们在IDs中有效。它们必须被删除或以不同方式转义。将我的方法从“尽可能少地更改字符串”更改为“比抱歉更安全”我必须更改
返回字符。isLetter(s.get(0)?s:“I”+s;
by
返回字符。isLetter(s.charAt(0))?s:“I”+s;
因为缺少括号,并且未定义方法get on String。
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"