在Java中解析xml时是否可以忽略/跳过节点

时间:2010-07-12 18:33:45

标签: java xml

我正在尝试从此XML中删除SOAPns2个节点:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"       SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns2:createCustomer>
    <Customer>
        <CustomerId/>
        <names>
            <firstName>fName</firstName>
            <lastName>lName</lastName>
            <middleName>nName</middleName>
            <nickName/>
            </names>
        <addressList>
            <address>
                <streetInfo>
                    <houseNumber>22</houseNumber>
                    <baseName>Street base name</baseName>
                    <district>kewl district</district>
                    </streetInfo>
                <zipcode>22231</zipcode>
                <state>xxx</state>
                <country>xxxz</country>
                <primary>true</primary>
                </address>
            </addressList>
        <SSN>561381</SSN>
        <phone>
            <homePhone>123123123</homePhone>
            <officePhone/>
            <homePhone>21319414</homePhone>
            </phone>
        <preferred>true</preferred>
        </Customer>
        </ns2:createCustomer>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

在此之前是否可以:

Document doc = parser.parse(xmlFile); 
NodeList startlist = doc.getChildNodes();

我尝试将其作为String读取,然后将其写回XML文件,如下所示:

private void preParsing(String fileName,String ...tags) {

        try {

            BufferedReader br = new BufferedReader(new FileReader(new File(fileName)));
            StringBuilder sb = new StringBuilder();
            String line;

            while ((line = br.readLine()) != null) {
                for (String string : tags) {
                    if(!line.contains(string)){
                        sb.append(line);
                        sb.append("\n");
                    }
                }
            }           

            System.out.println(sb.toString());

            br.close();

        } catch (IOException e) {
            System.err.println("Error occured: " + e.getMessage());
        }

    }

如果我只忽略一个标签,那就有用了:

preParsing("src/main/resources/test.xml", "SOAP");

但是当我将多个标记参数传递给忽略/从文件中删除时,它不起作用。我敢肯定有更优雅的方式这样做我只是想不到任何。

3 个答案:

答案 0 :(得分:3)

您可以使用StAX filter

class MyFilter implements EventFilter {
  private final List<String> filtered = Arrays.asList("SOAP-ENV:Envelope",
      "SOAP-ENV:Body", "ns2:createCustomer");

  @Override
  public boolean accept(XMLEvent event) {
    if (event.isStartElement())
      for (String elementName : filtered)
        if (event.asStartElement().getName().getLocalPart().equals(
            elementName))
          return false;
    if (event.isEndElement())
      for (String elementName : filtered)
        if (event.asEndElement().getName().getLocalPart().equals(
            elementName))
          return false;
    return true;
  }
}

用法:

DOMResult result = new DOMResult();
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
xmlInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false);
XMLEventReader reader = xmlInputFactory
    .createXMLEventReader(new StreamSource(new File("soap.xml")));
reader = xmlInputFactory.createFilteredReader(reader, new MyFilter());
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.transform(new StAXSource(reader), result);
Document document = (Document) result.getNode();

仅供参考:SOAP-ENV和ns2不是元素;它们是名称空间前缀。该文档格式错误 - 缺少名称空间声明&amp;上面的代码不是我为有效的命名空间文档编写的。

答案 1 :(得分:0)

最好的办法是正常加载文档,并使用XPath来获取所需的部分。

How to read XML using XPath in Java

有一些好消息

答案 2 :(得分:0)

操作XML文档的常用方法是使用XSLT。这例如允许您编写可以删除特定命名空间中的任何标记的过滤器等等。

XSLT语言与Java完全不同,但是从1.4开始,Java中就有一个XSLT处理器(检查模板和Transformer类),所以它得到了很好的支持。