java - 如何使用 SAX 解析器删除 xml 命名空间

标签 java xml saxparser

我需要使用 SAX 解析器进行 xml 转换,为此我需要从 xml 中删除 namespace 。由于我们正在处理巨大的 xml,因此我需要使用 SAX 解析器。

示例输入 xml:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
 xmlns:ns2="http://www.google.com/generation/type">
    <ns2:meta>
        <gender xmlns="" xmlns:ns5="http://www.google.com/generation">M</gender>
        <dateOfBirth xmlns="" xmlns:ns5="http://www.google.com/generation">1976-07-19</dateOfBirth>
        <ns2:languageRef>ENG</ns2:languageRef>
    </ns2:meta>
    <root>

在 SAX 解析器的帮助下,我需要以下输出。

       <root>
            <meta>
                <gender>M</gender>
                <dateOfBirth>1976-07-19</dateOfBirth>
                <languageRef>ENG</languageRef>
            </ns2:meta>
        <root>

提前致谢..

我尝试过的代码,

我尝试使用 XMLFlterImpl,

XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {

  @Override
  public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {

    if (qName.contains(":")) {
      String[] data = data = qName.split(":");


      super.startElement(uri, localName, data[1], atts);
    } else {
      super.startElement(uri, localName, qName, atts);
    }
  } 

这会删除元素名称前缀(命名空间),但不确定如何删除命名空间属性

最佳答案

编辑:

好的,根据 @MichaelKay 的评论指导,这是我的更新答案。

从标签中删除命名空间:

正如他的回答中所建议的,startElement应该有""代替uri结束标签怎么样?: 在你的问题中我不明白你为什么想要 ns2结束meta标签,特别是当您想要删除起始标签时。 我假设您也希望将其删除作为结束标记。同样endElement还应该有""代替uri

过滤 XMLNS 属性:

您可以创建一个新的 AttributesImpl 。然后浏览属性列表并检查 QName 是否以 xmlns 开头,如果没有将其添加到 AttributesImpl并在 startElement 中使用它如:

super.startElement("", localName, data[1], aImpl);

另请注意,根据@MartinHonnen,是的属性'uri也应该是“”并且也是qName应该像元素一样没有前缀。但是,如果您想保留属性名称(我认为您不想这样做),您可以保留 atts.getQName(i)照原样。

还将命名空间功能设置为 false,例如:

xf.setFeature("http://xml.org/sax/features/namespaces", false);

代码:

try {

   InputSource file = new InputSource("filterns.xml");

   XMLFilterImpl xf = new XMLFilterImpl(
           XMLReaderFactory.createXMLReader()) {
       @Override
       public void startElement(String uri, String localName,
           String qName, Attributes atts) throws SAXException {

               AttributesImpl aImpl = new AttributesImpl();

                int l = atts.getLength();
                for (int i = 0; i < l; i++) {

                    if (atts.getQName(i) != null
                            && atts.getQName(i).startsWith("xmlns")) {
                        continue;
                    } else {
                        String aQName = atts.getQName(i);
                        String[] s = aQName.split(":");
                        if (s.length > 1) {
                            aQName = s[1];
                        }

                        aImpl.addAttribute("",
                                atts.getLocalName(i), aQName,
                                atts.getType(i), atts.getValue(i));
                    }

                }

                String[] s = qName.split(":");
                if (s.length > 1) {
                    super.startElement("", localName, s[1], aImpl);
                } else {
                    super.startElement("", localName, qName, aImpl);
                }

       }

       @Override
       public void endElement(String uri, String localName,
              String qName) throws SAXException {

              String[] s = qName.split(":");
              if (s.length > 1) {
                 super.endElement("", localName, s[1]);
               } else {
                  super.endElement("", localName, qName);
                 }

       }

       @Override
       public void startPrefixMapping(String prefix, String uri) {
       }

   };

   xf.setFeature("http://xml.org/sax/features/namespaces", false);
   SAXSource src = new SAXSource(xf, file);

   StringWriter stringWriter = new StringWriter();
   TransformerFactory transformerFactory = TransformerFactory
           .newInstance();
   Transformer transformer = transformerFactory.newTransformer();
   transformer.setOutputProperty(OutputKeys.INDENT, "yes");
   transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"yes");
   transformer.transform(src, new StreamResult(stringWriter));

   String xml = stringWriter.toString();
   System.out.println(xml);

} catch (Exception e) {
   e.printStackTrace();
}

关于java - 如何使用 SAX 解析器删除 xml 命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44969384/

相关文章:

java - xml使用sax解析器从子标签解析数据

java - 当队列类型包含泛型时,对阻塞队列进行毒害

java - 将使用 Netbeans 创建的 Java 程序固定在任务栏上?

java - JDBC VS Hibernate

java - 如何使用 java.util.Date 设置 JDatePicker 的 JFormattedTextField 上的日期 (JDatePickerImpl 1.3.4)

java - 循环通过 XML 来构建对象

java - Android:我无法通过 id 获取布局对象

java - cvc-elt.1 : Cannot find the declaration of element 'NewIssue'

c# - 如何使用 linq to XML 添加/插入条件节点到 XML

Java:如何使用 SAX 确定 XML 解析期间的深度级别