java-如何检查字符串是否是有效的XML元素名?

java-如何检查字符串是否是有效的XML元素名?,java,xml,Java,Xml,您知道java中的一个函数,它将验证字符串是否是一个好的XML元素名 表格W3学校: XML元素必须遵循以下命名规则 规则: 名称可以包含字母、数字和其他字符 名称不能以数字或标点符号开头 名称不能以字母xml(或xml或xml等)开头 名称不能包含空格 我发现了提供正则表达式解决方案的其他问题,难道没有一个函数已经做到了这一点吗?规范中的相关产品是 名称::==NameStartChar NameChar* 美国政府官员表示:这名政府官员::::::::“(A-A-Z)A-Z)A-Z[A-A-

您知道java中的一个函数,它将验证字符串是否是一个好的XML元素名

表格W3学校:

XML元素必须遵循以下命名规则 规则:

  • 名称可以包含字母、数字和其他字符
  • 名称不能以数字或标点符号开头
  • 名称不能以字母xml(或xml或xml等)开头
  • 名称不能包含空格

  • 我发现了提供正则表达式解决方案的其他问题,难道没有一个函数已经做到了这一点吗?

    规范中的相关产品是

    名称::==NameStartChar NameChar*

    美国政府官员表示:这名政府官员::::::::“(A-A-Z)A-Z)A-Z[A-A-Z]方方方方方方:::::::::::::::::::::::::::::::::::::::::::“:::::::::::::::::::::::::::::::::::::::::::::::::::[目前目前目前目前目前:::::::::::[[[答答答(A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-Z)A-A-Z)A-Z)A-Z方方方方方(A-Z)方方方方方方方方方方(A-Z)方方方方0-#x2FEF]|[#x3001-#xD7FF]|[#xF900-#xFDCF]|[#xFDF0-#xFFFD]|[#x10000-#xefff]

    NameChar::=NameStartChar-“[0-9]|##xB7 |[#x0300-#x036F]|[#x203F-#x2040]

    因此,与之匹配的正则表达式是

    "^[:A-Z_a-z\\u00C0\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02ff\\u0370-\\u037d"
    + "\\u037f-\\u1fff\\u200c\\u200d\\u2070-\\u218f\\u2c00-\\u2fef\\u3001-\\ud7ff"
    + "\\uf900-\\ufdcf\\ufdf0-\\ufffd\\x10000-\\xEFFFF]"
    + "[:A-Z_a-z\\u00C0\\u00D6\\u00D8-\\u00F6"
    + "\\u00F8-\\u02ff\\u0370-\\u037d\\u037f-\\u1fff\\u200c\\u200d\\u2070-\\u218f"
    + "\\u2c00-\\u2fef\\u3001-\\udfff\\uf900-\\ufdcf\\ufdf0-\\ufffd\\-\\.0-9"
    + "\\u00b7\\u0300-\\u036f\\u203f-\\u2040]*\\Z"
    
    如果要处理名称空间名称,需要确保最多有一个冒号,因此

    "^[A-Z_a-z\\u00C0\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02ff\\u0370-\\u037d"
    + "\\u037f-\\u1fff\\u200c\\u200d\\u2070-\\u218f\\u2c00-\\u2fef\\u3001-\\udfff"
    + "\\uf900-\\ufdcf\\ufdf0-\\ufffd]"
    + "[A-Z_a-z\\u00C0\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02ff\\u0370-\\u037d"
    + "\\u037f-\\u1fff\\u200c\\u200d\\u2070-\\u218f\\u2c00-\\u2fef\\u3001-\\udfff"
    + "\\uf900-\\ufdcf\\ufdf0-\\ufffd\\-\\.0-9\\u00b7\\u0300-\\u036f\\u203f-\\u2040]*"
    + "(?::[A-Z_a-z\\u00C0\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02ff\\u0370-\\u037d"
    + "\\u037f-\\u1fff\\u200c\\u200d\\u2070-\\u218f\\u2c00-\\u2fef\\u3001-\\udfff"
    + "\\uf900-\\ufdcf\\ufdf0-\\ufffd]"
    + "[A-Z_a-z\\u00C0\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02ff\\u0370-\\u037d"
    + "\\u037f-\\u1fff\\u200c\\u200d\\u2070-\\u218f\\u2c00-\\u2fef\\u3001-\\udfff"
    + "\\uf900-\\ufdcf\\ufdf0-\\ufffd\\-\\.0-9\\u00b7\\u0300-\\u036f\\u203f-\\u2040]*)?\\Z"
    

    (错过了另一个03gf;同时更改为036f)

    如果您使用的是Xerces XML解析器,您可以使用XMLChar(或XML11Char)类,如下所示:

    org.apache.xerces.util.XMLChar.isValidName(String name)
    

    还有
    isValidName

    的示例代码,使用org.apache.xerces实用程序是一种很好的方法;但是,如果您需要坚持使用作为标准Java API一部分的Java代码,则以下代码可以做到这一点:

    public void parse(String xml) throws Exception {
    
        XMLReader parser = XMLReaderFactory.createXMLReader();
        parser.setContentHandler(new DefaultHandler());
        InputSource source = new InputSource(new ByteArrayInputStream(xml.getBytes()));
        parser.parse(source);
    }
    

    作为当前添加到的:

    在非公开的
    com.sun.*
    软件包中,至少Oracle的JDK1.8(可能也比较旧)在内部使用Xerces解析器。您不应该直接使用这些类中的任何实现,因为在JDK的未来版本中,它们可能会在不另行通知的情况下发生更改!但是,xml元素名称有效性检查所需的代码封装得非常好,可以复制到您自己的代码中。这样,就可以避免对外部库的另一种依赖

    这是从内部类
    com.sun.org.apache.xerces.internal.util.XMLChar
    获取的必需代码:

    public class XMLChar {
    
        /** Character flags. */
        private static final byte[] CHARS = new byte[1 << 16];
    
        /** Name start character mask. */
        public static final int MASK_NAME_START = 0x04;
    
        /** Name character mask. */
        public static final int MASK_NAME = 0x08;
    
        static {
            // Initializing the Character Flag Array
            // Code generated by: XMLCharGenerator.
    
            CHARS[9] = 35;
            CHARS[10] = 19;
            CHARS[13] = 19;
    
            // ...
            // the entire static block must be copied
        }
    
        /**
         * Check to see if a string is a valid Name according to [5]
         * in the XML 1.0 Recommendation
         *
         * @param name string to check
         * @return true if name is a valid Name
         */
        public static boolean isValidName(String name) {
            final int length = name.length();
            if (length == 0) {
                return false;
            }
            char ch = name.charAt(0);
            if (!isNameStart(ch)) {
                return false;
            }
            for (int i = 1; i < length; ++i) {
                ch = name.charAt(i);
                if (!isName(ch)) {
                    return false;
                }
            }
            return true;
        }
    
        /**
         * Returns true if the specified character is a valid name start
         * character as defined by production [5] in the XML 1.0
         * specification.
         *
         * @param c The character to check.
         */
        public static boolean isNameStart(int c) {
            return c < 0x10000 && (CHARS[c] & MASK_NAME_START) != 0;
        }
    
        /**
         * Returns true if the specified character is a valid name
         * character as defined by production [4] in the XML 1.0
         * specification.
         *
         * @param c The character to check.
         */
        public static boolean isName(int c) {
            return c < 0x10000 && (CHARS[c] & MASK_NAME) != 0;
        }
    }
    
    公共类XMLChar{
    /**字符标志*/
    
    private static final byte[]CHARS=new byte[1但请注意,为该任务实例化XMLReader的开销相当高,特别是如果使用JAXP工厂搜索完成的话。当然,如果重复使用的次数足够多,就不会有问题。很好,它看起来正是我要寻找的,但您知道为什么XMLChar.isValidName(“xml”)返回true吗?(问题批准)“xml”在不区分大小写的情况下是有效的,但保留。您可能会在实践中遇到它。如果您正在检查输入,您可能需要添加&&!name.toLowerCase().startsWith(“xml”)名称有效性检查所需的代码实际上只包含几行,可以复制出来以避免另一个外部依赖关系。有关详细信息,请参阅。谢谢,这是否意味着规则3不正确“3.名称不能以字母xml(或xml,或xml等)开头”答案是“是”和“否”。“名称以字符串开头”xml“,或与任何匹配的字符串(('X'|'X')('M'|'M')('L'|'L'))保留,以便在本规范或本规范的未来版本中进行标准化。”因此,它是一个有效名称,但它是保留的。它不会使用jdk 11复制:错误:[错误](包com.sun.org.apache.xerces.internal.util在模块java.xml中声明,模块java.xml不导出它)