提交 38b8262e 编写于 作者: J Juergen Hoeller

XML parsing tests pass on non-English locales now, plus a revised exception...

XML parsing tests pass on non-English locales now, plus a revised exception message and some minor polishing

Issue: SPR-13136
上级 9c3580d0
...@@ -37,7 +37,6 @@ import java.util.Calendar; ...@@ -37,7 +37,6 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import javax.activation.DataHandler; import javax.activation.DataHandler;
import javax.activation.DataSource; import javax.activation.DataSource;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
......
...@@ -16,18 +16,10 @@ ...@@ -16,18 +16,10 @@
package org.springframework.oxm.castor; package org.springframework.oxm.castor;
import static junit.framework.Assert.assertEquals;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import javax.xml.transform.sax.SAXSource; import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamSource;
...@@ -41,6 +33,13 @@ import org.springframework.oxm.AbstractUnmarshallerTests; ...@@ -41,6 +33,13 @@ import org.springframework.oxm.AbstractUnmarshallerTests;
import org.springframework.oxm.MarshallingException; import org.springframework.oxm.MarshallingException;
import org.springframework.oxm.Unmarshaller; import org.springframework.oxm.Unmarshaller;
import static junit.framework.Assert.assertEquals;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.*;
/** /**
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Jakub Narloch * @author Jakub Narloch
......
...@@ -74,6 +74,7 @@ public class Jaxb2MarshallerTests extends AbstractMarshallerTests { ...@@ -74,6 +74,7 @@ public class Jaxb2MarshallerTests extends AbstractMarshallerTests {
private Flights flights; private Flights flights;
@Override @Override
public Marshaller createMarshaller() throws Exception { public Marshaller createMarshaller() throws Exception {
marshaller = new Jaxb2Marshaller(); marshaller = new Jaxb2Marshaller();
...@@ -91,6 +92,7 @@ public class Jaxb2MarshallerTests extends AbstractMarshallerTests { ...@@ -91,6 +92,7 @@ public class Jaxb2MarshallerTests extends AbstractMarshallerTests {
return flights; return flights;
} }
@Test @Test
public void marshalSAXResult() throws Exception { public void marshalSAXResult() throws Exception {
ContentHandler contentHandler = mock(ContentHandler.class); ContentHandler contentHandler = mock(ContentHandler.class);
......
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -205,7 +205,7 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractHttpM ...@@ -205,7 +205,7 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractHttpM
return this.objectMapper.readValue(inputMessage.getBody(), javaType); return this.objectMapper.readValue(inputMessage.getBody(), javaType);
} }
catch (IOException ex) { catch (IOException ex) {
throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex); throw new HttpMessageNotReadableException("Could not read document: " + ex.getMessage(), ex);
} }
} }
......
...@@ -27,7 +27,6 @@ import java.util.List; ...@@ -27,7 +27,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.TimeZone; import java.util.TimeZone;
import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLResolver; import javax.xml.stream.XMLResolver;
......
...@@ -18,7 +18,6 @@ package org.springframework.http.converter.xml; ...@@ -18,7 +18,6 @@ package org.springframework.http.converter.xml;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException; import javax.xml.bind.JAXBException;
import javax.xml.bind.MarshalException; import javax.xml.bind.MarshalException;
......
...@@ -23,7 +23,6 @@ import java.io.OutputStream; ...@@ -23,7 +23,6 @@ import java.io.OutputStream;
import java.io.StringReader; import java.io.StringReader;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
......
...@@ -16,13 +16,10 @@ ...@@ -16,13 +16,10 @@
package org.springframework.http.converter.xml; package org.springframework.http.converter.xml;
import static org.junit.Assert.*;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
...@@ -40,6 +37,8 @@ import org.springframework.core.io.Resource; ...@@ -40,6 +37,8 @@ import org.springframework.core.io.Resource;
import org.springframework.http.MockHttpInputMessage; import org.springframework.http.MockHttpInputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotReadableException;
import static org.junit.Assert.*;
/** /**
* Test fixture for {@link Jaxb2CollectionHttpMessageConverter}. * Test fixture for {@link Jaxb2CollectionHttpMessageConverter}.
* *
...@@ -71,6 +70,7 @@ public class Jaxb2CollectionHttpMessageConverterTests { ...@@ -71,6 +70,7 @@ public class Jaxb2CollectionHttpMessageConverterTests {
typeSetType = new ParameterizedTypeReference<Set<TestType>>() {}.getType(); typeSetType = new ParameterizedTypeReference<Set<TestType>>() {}.getType();
} }
@Test @Test
public void canRead() throws Exception { public void canRead() throws Exception {
assertTrue(converter.canRead(rootElementListType, null, null)); assertTrue(converter.canRead(rootElementListType, null, null));
...@@ -206,6 +206,7 @@ public class Jaxb2CollectionHttpMessageConverterTests { ...@@ -206,6 +206,7 @@ public class Jaxb2CollectionHttpMessageConverterTests {
this.converter.read(this.rootElementListType, null, inputMessage); this.converter.read(this.rootElementListType, null, inputMessage);
} }
@XmlRootElement @XmlRootElement
public static class RootElement { public static class RootElement {
...@@ -240,6 +241,7 @@ public class Jaxb2CollectionHttpMessageConverterTests { ...@@ -240,6 +241,7 @@ public class Jaxb2CollectionHttpMessageConverterTests {
} }
} }
@XmlType @XmlType
public static class TestType { public static class TestType {
......
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -16,13 +16,7 @@ ...@@ -16,13 +16,7 @@
package org.springframework.http.converter.xml; package org.springframework.http.converter.xml;
import static org.custommonkey.xmlunit.XMLAssert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import javax.xml.bind.Marshaller; import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller; import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlAttribute;
...@@ -47,6 +41,11 @@ import org.springframework.http.MockHttpInputMessage; ...@@ -47,6 +41,11 @@ import org.springframework.http.MockHttpInputMessage;
import org.springframework.http.MockHttpOutputMessage; import org.springframework.http.MockHttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotReadableException;
import static org.custommonkey.xmlunit.XMLAssert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/** /**
* Tests for {@link Jaxb2RootElementHttpMessageConverter}. * Tests for {@link Jaxb2RootElementHttpMessageConverter}.
* *
...@@ -78,6 +77,7 @@ public class Jaxb2RootElementHttpMessageConverterTests { ...@@ -78,6 +77,7 @@ public class Jaxb2RootElementHttpMessageConverterTests {
rootElementCglib = (RootElement) proxy.getProxy(); rootElementCglib = (RootElement) proxy.getProxy();
} }
@Test @Test
public void canRead() throws Exception { public void canRead() throws Exception {
assertTrue("Converter does not support reading @XmlRootElement", converter.canRead(RootElement.class, null)); assertTrue("Converter does not support reading @XmlRootElement", converter.canRead(RootElement.class, null));
...@@ -165,7 +165,7 @@ public class Jaxb2RootElementHttpMessageConverterTests { ...@@ -165,7 +165,7 @@ public class Jaxb2RootElementHttpMessageConverterTests {
"<rootElement><external>&lol9;</external></rootElement>"; "<rootElement><external>&lol9;</external></rootElement>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8")); MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
this.thrown.expect(HttpMessageNotReadableException.class); this.thrown.expect(HttpMessageNotReadableException.class);
this.thrown.expectMessage("DOCTYPE is disallowed"); this.thrown.expectMessage("DOCTYPE");
this.converter.read(RootElement.class, inputMessage); this.converter.read(RootElement.class, inputMessage);
} }
...@@ -210,6 +210,7 @@ public class Jaxb2RootElementHttpMessageConverterTests { ...@@ -210,6 +210,7 @@ public class Jaxb2RootElementHttpMessageConverterTests {
assertEquals("b", result.getElement().getField2()); assertEquals("b", result.getElement().getField2());
} }
@XmlRootElement @XmlRootElement
public static class RootElement { public static class RootElement {
...@@ -228,6 +229,7 @@ public class Jaxb2RootElementHttpMessageConverterTests { ...@@ -228,6 +229,7 @@ public class Jaxb2RootElementHttpMessageConverterTests {
} }
} }
@XmlType @XmlType
public static class Type { public static class Type {
...@@ -236,10 +238,11 @@ public class Jaxb2RootElementHttpMessageConverterTests { ...@@ -236,10 +238,11 @@ public class Jaxb2RootElementHttpMessageConverterTests {
} }
public static class RootElementSubclass extends RootElement {
public static class RootElementSubclass extends RootElement {
} }
public static class MyJaxb2RootElementHttpMessageConverter extends Jaxb2RootElementHttpMessageConverter { public static class MyJaxb2RootElementHttpMessageConverter extends Jaxb2RootElementHttpMessageConverter {
@Override @Override
...@@ -253,8 +256,11 @@ public class Jaxb2RootElementHttpMessageConverterTests { ...@@ -253,8 +256,11 @@ public class Jaxb2RootElementHttpMessageConverterTests {
} }
} }
public static class MyCustomElement { public static class MyCustomElement {
private String field1; private String field1;
private String field2; private String field2;
public MyCustomElement() { public MyCustomElement() {
...@@ -282,6 +288,7 @@ public class Jaxb2RootElementHttpMessageConverterTests { ...@@ -282,6 +288,7 @@ public class Jaxb2RootElementHttpMessageConverterTests {
} }
} }
@XmlRootElement @XmlRootElement
public static class MyRootElement { public static class MyRootElement {
...@@ -305,6 +312,7 @@ public class Jaxb2RootElementHttpMessageConverterTests { ...@@ -305,6 +312,7 @@ public class Jaxb2RootElementHttpMessageConverterTests {
} }
} }
public static class MyCustomElementAdapter extends XmlAdapter<String, MyCustomElement> { public static class MyCustomElementAdapter extends XmlAdapter<String, MyCustomElement> {
@Override @Override
......
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -26,10 +26,8 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper; ...@@ -26,10 +26,8 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.xml.sax.SAXException;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpOutputMessage; import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.MockHttpInputMessage; import org.springframework.http.MockHttpInputMessage;
...@@ -45,6 +43,7 @@ import static org.junit.Assert.*; ...@@ -45,6 +43,7 @@ import static org.junit.Assert.*;
* Jackson 2.x XML converter tests. * Jackson 2.x XML converter tests.
* *
* @author Sebastien Deleuze * @author Sebastien Deleuze
* @author Rossen Stoyanchev
*/ */
public class MappingJackson2XmlHttpMessageConverterTests { public class MappingJackson2XmlHttpMessageConverterTests {
...@@ -70,17 +69,16 @@ public class MappingJackson2XmlHttpMessageConverterTests { ...@@ -70,17 +69,16 @@ public class MappingJackson2XmlHttpMessageConverterTests {
@Test @Test
public void read() throws IOException { public void read() throws IOException {
String body = String body = "<MyBean><string>Foo</string><number>42</number><fraction>42.0</fraction><array><array>Foo</array><array>Bar</array></array><bool>true</bool><bytes>AQI=</bytes></MyBean>";
"<MyBean><string>Foo</string><number>42</number><fraction>42.0</fraction><array><array>Foo</array><array>Bar</array></array><bool>true</bool><bytes>AQI=</bytes></MyBean>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8")); MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml")); inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
MyBean result = (MyBean) converter.read(MyBean.class, inputMessage); MyBean result = (MyBean) converter.read(MyBean.class, inputMessage);
assertEquals("Foo", result.getString()); assertEquals("Foo", result.getString());
assertEquals(42, result.getNumber()); assertEquals(42, result.getNumber());
assertEquals(42F, result.getFraction(), 0F); assertEquals(42F, result.getFraction(), 0F);
assertArrayEquals(new String[] {"Foo", "Bar"}, result.getArray()); assertArrayEquals(new String[]{"Foo", "Bar"}, result.getArray());
assertTrue(result.isBool()); assertTrue(result.isBool());
assertArrayEquals(new byte[] {0x1, 0x2}, result.getBytes()); assertArrayEquals(new byte[]{0x1, 0x2}, result.getBytes());
} }
@Test @Test
...@@ -149,7 +147,6 @@ public class MappingJackson2XmlHttpMessageConverterTests { ...@@ -149,7 +147,6 @@ public class MappingJackson2XmlHttpMessageConverterTests {
@Test @Test
public void readWithExternalReference() throws IOException { public void readWithExternalReference() throws IOException {
String body = "<!DOCTYPE MyBean SYSTEM \"http://192.168.28.42/1.jsp\" [" + String body = "<!DOCTYPE MyBean SYSTEM \"http://192.168.28.42/1.jsp\" [" +
" <!ELEMENT root ANY >\n" + " <!ELEMENT root ANY >\n" +
" <!ENTITY ext SYSTEM \"" + " <!ENTITY ext SYSTEM \"" +
...@@ -160,14 +157,11 @@ public class MappingJackson2XmlHttpMessageConverterTests { ...@@ -160,14 +157,11 @@ public class MappingJackson2XmlHttpMessageConverterTests {
inputMessage.getHeaders().setContentType(new MediaType("application", "xml")); inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
this.thrown.expect(HttpMessageNotReadableException.class); this.thrown.expect(HttpMessageNotReadableException.class);
this.thrown.expectMessage("entity \"ext\"");
this.converter.read(MyBean.class, inputMessage); this.converter.read(MyBean.class, inputMessage);
} }
@Test @Test
public void readWithXmlBomb() throws IOException { public void readWithXmlBomb() throws IOException {
// https://en.wikipedia.org/wiki/Billion_laughs // https://en.wikipedia.org/wiki/Billion_laughs
// https://msdn.microsoft.com/en-us/magazine/ee335713.aspx // https://msdn.microsoft.com/en-us/magazine/ee335713.aspx
String body = "<?xml version=\"1.0\"?>\n" + String body = "<?xml version=\"1.0\"?>\n" +
...@@ -190,15 +184,11 @@ public class MappingJackson2XmlHttpMessageConverterTests { ...@@ -190,15 +184,11 @@ public class MappingJackson2XmlHttpMessageConverterTests {
inputMessage.getHeaders().setContentType(new MediaType("application", "xml")); inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
this.thrown.expect(HttpMessageNotReadableException.class); this.thrown.expect(HttpMessageNotReadableException.class);
this.thrown.expectMessage("entity \"lol9\"");
this.converter.read(MyBean.class, inputMessage); this.converter.read(MyBean.class, inputMessage);
} }
private void writeInternal(Object object, HttpOutputMessage outputMessage) private void writeInternal(Object object, HttpOutputMessage outputMessage) throws Exception {
throws NoSuchMethodException, InvocationTargetException,
IllegalAccessException {
Method method = AbstractJackson2HttpMessageConverter.class.getDeclaredMethod( Method method = AbstractJackson2HttpMessageConverter.class.getDeclaredMethod(
"writeInternal", Object.class, HttpOutputMessage.class); "writeInternal", Object.class, HttpOutputMessage.class);
method.setAccessible(true); method.setAccessible(true);
...@@ -269,9 +259,12 @@ public class MappingJackson2XmlHttpMessageConverterTests { ...@@ -269,9 +259,12 @@ public class MappingJackson2XmlHttpMessageConverterTests {
} }
} }
private interface MyJacksonView1 {}; private interface MyJacksonView1 {};
private interface MyJacksonView2 {}; private interface MyJacksonView2 {};
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static class JacksonViewBean { private static class JacksonViewBean {
...@@ -308,6 +301,7 @@ public class MappingJackson2XmlHttpMessageConverterTests { ...@@ -308,6 +301,7 @@ public class MappingJackson2XmlHttpMessageConverterTests {
} }
} }
@SuppressWarnings("serial") @SuppressWarnings("serial")
private static class MyXmlMapper extends XmlMapper { private static class MyXmlMapper extends XmlMapper {
} }
......
...@@ -16,16 +16,10 @@ ...@@ -16,16 +16,10 @@
package org.springframework.http.converter.xml; package org.springframework.http.converter.xml;
import static org.custommonkey.xmlunit.XMLAssert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
import static org.junit.Assert.assertTrue;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.StringReader; import java.io.StringReader;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source; import javax.xml.transform.Source;
...@@ -53,6 +47,11 @@ import org.springframework.http.MockHttpOutputMessage; ...@@ -53,6 +47,11 @@ import org.springframework.http.MockHttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.util.FileCopyUtils; import org.springframework.util.FileCopyUtils;
import static org.custommonkey.xmlunit.XMLAssert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
import static org.junit.Assert.assertTrue;
// Do NOT statically import org.junit.Assert.*, since XMLAssert extends junit.framework.Assert // Do NOT statically import org.junit.Assert.*, since XMLAssert extends junit.framework.Assert
/** /**
...@@ -80,6 +79,7 @@ public class SourceHttpMessageConverterTests { ...@@ -80,6 +79,7 @@ public class SourceHttpMessageConverterTests {
" <!ENTITY ext SYSTEM \"" + external.getURI() + "\" >]><root>&ext;</root>"; " <!ENTITY ext SYSTEM \"" + external.getURI() + "\" >]><root>&ext;</root>";
} }
@Test @Test
public void canRead() { public void canRead() {
assertTrue(converter.canRead(Source.class, new MediaType("application", "xml"))); assertTrue(converter.canRead(Source.class, new MediaType("application", "xml")));
...@@ -135,7 +135,7 @@ public class SourceHttpMessageConverterTests { ...@@ -135,7 +135,7 @@ public class SourceHttpMessageConverterTests {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8")); MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
this.thrown.expect(HttpMessageNotReadableException.class); this.thrown.expect(HttpMessageNotReadableException.class);
this.thrown.expectMessage("DOCTYPE is disallowed"); this.thrown.expectMessage("DOCTYPE");
this.converter.read(DOMSource.class, inputMessage); this.converter.read(DOMSource.class, inputMessage);
} }
...@@ -192,7 +192,7 @@ public class SourceHttpMessageConverterTests { ...@@ -192,7 +192,7 @@ public class SourceHttpMessageConverterTests {
SAXSource result = (SAXSource) this.converter.read(SAXSource.class, inputMessage); SAXSource result = (SAXSource) this.converter.read(SAXSource.class, inputMessage);
this.thrown.expect(SAXException.class); this.thrown.expect(SAXException.class);
this.thrown.expectMessage("DOCTYPE is disallowed"); this.thrown.expectMessage("DOCTYPE");
InputSource inputSource = result.getInputSource(); InputSource inputSource = result.getInputSource();
XMLReader reader = result.getXMLReader(); XMLReader reader = result.getXMLReader();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册