【问题标题】:how to unescape XML in java如何在java中取消转义XML
【发布时间】:2011-02-19 12:13:03
【问题描述】:

我需要对包含转义 XML 标记的 xml 字符串进行转义:

<
>
&
etc...

我确实找到了一些可以执行此任务的库,但我宁愿使用可以执行此任务的单一方法。

有人可以帮忙吗?

干杯, 巴斯·亨德里克斯

【问题讨论】:

    标签: java xml escaping


    【解决方案1】:
    StringEscapeUtils.unescapeXml(xml)
    

    (commons-lang, download)

    【讨论】:

    • “但我宁愿使用可以执行此任务的单一方法。”
    • Bas,阅读 commons-lang 的源代码,看看是否值得重新发明轮子而不是仅仅使用它。
    • @Bas - 标准 Java 库中没有任何内容可以执行此操作,因此您要么使用可以为您执行此操作的第三方库,要么您必须自己编写(不推荐)。
    【解决方案2】:

    这里有一个简单的方法来对 XML 进行转义。它处理预定义的 XML 实体和十进制数字实体 (nnnn;)。修改它以处理十六进制实体 (hhhh;) 应该很简单。

    public static String unescapeXML( final String xml )
    {
        Pattern xmlEntityRegex = Pattern.compile( "&(#?)([^;]+);" );
        //Unfortunately, Matcher requires a StringBuffer instead of a StringBuilder
        StringBuffer unescapedOutput = new StringBuffer( xml.length() );
    
        Matcher m = xmlEntityRegex.matcher( xml );
        Map<String,String> builtinEntities = null;
        String entity;
        String hashmark;
        String ent;
        int code;
        while ( m.find() ) {
            ent = m.group(2);
            hashmark = m.group(1);
            if ( (hashmark != null) && (hashmark.length() > 0) ) {
                code = Integer.parseInt( ent );
                entity = Character.toString( (char) code );
            } else {
                //must be a non-numerical entity
                if ( builtinEntities == null ) {
                    builtinEntities = buildBuiltinXMLEntityMap();
                }
                entity = builtinEntities.get( ent );
                if ( entity == null ) {
                    //not a known entity - ignore it
                    entity = "&" + ent + ';';
                }
            }
            m.appendReplacement( unescapedOutput, entity );
        }
        m.appendTail( unescapedOutput );
    
        return unescapedOutput.toString();
    }
    
    private static Map<String,String> buildBuiltinXMLEntityMap()
    {
        Map<String,String> entities = new HashMap<String,String>(10);
        entities.put( "lt", "<" );
        entities.put( "gt", ">" );
        entities.put( "amp", "&" );
        entities.put( "apos", "'" );
        entities.put( "quot", "\"" );
        return entities;
    }
    

    【讨论】:

      【解决方案3】:

      这是我用十分钟写的一篇。它不使用正则表达式,只使用简单的迭代。我不认为这可以增强得更快。

      public static String unescape(final String text) {
          StringBuilder result = new StringBuilder(text.length());
          int i = 0;
          int n = text.length();
          while (i < n) {
              char charAt = text.charAt(i);
              if (charAt != '&') {
                  result.append(charAt);
                  i++;
              } else {
                  if (text.startsWith("&amp;", i)) {
                      result.append('&');
                      i += 5;
                  } else if (text.startsWith("&apos;", i)) {
                      result.append('\'');
                      i += 6;
                  } else if (text.startsWith("&quot;", i)) {
                      result.append('"');
                      i += 6;
                  } else if (text.startsWith("&lt;", i)) {
                      result.append('<');
                      i += 4;
                  } else if (text.startsWith("&gt;", i)) {
                      result.append('>');
                      i += 4;
                  } else i++;
              }
          }
          return result.toString();
      }
      

      【讨论】:

      • 这确实支持数字实体
      • 我喜欢这种简单的方法。但是,它会从输入中去除单个 & 符号。最后一个else 恕我直言:else { result.append(charAt); i++; }
      【解决方案4】:

      如果您使用 JSP,请使用来自 openutils-elfunctions 的 su:unescapeXml

      【讨论】:

        猜你喜欢
        • 2010-10-27
        • 1970-01-01
        • 1970-01-01
        • 2011-04-02
        • 2018-08-16
        • 1970-01-01
        • 2010-11-02
        相关资源
        最近更新 更多