ksoap2 android:需要将原始XML作为值,而不转义特殊字符
我正在使用ksoap2来使用SOAP WS。我唯一需要从库中得到的是验证信封并与WS通信,“body”xml是从其他地方使用简单xml的对象生成的 因此,我需要的是将xml(已作为字符串传递)作为值,但ksoap2使用>和<来转义我的xml标记 我在这里搜索过,我发现最相似的问题是哪一点哪一点。无论如何,我不想再次马歇尔一个对象,我的结构相当大,它还包括一个签名,我已经用另一个库解决了所有这些问题ksoap2 android:需要将原始XML作为值,而不转义特殊字符,android,xml,android-ksoap2,Android,Xml,Android Ksoap2,我正在使用ksoap2来使用SOAP WS。我唯一需要从库中得到的是验证信封并与WS通信,“body”xml是从其他地方使用简单xml的对象生成的 因此,我需要的是将xml(已作为字符串传递)作为值,但ksoap2使用>和<来转义我的xml标记 我在这里搜索过,我发现最相似的问题是哪一点哪一点。无论如何,我不想再次马歇尔一个对象,我的结构相当大,它还包括一个签名,我已经用另一个库解决了所有这些问题 所以,实际的问题是:在ksoap2android中有没有办法避免以字符串形式转义xml?我
所以,实际的问题是:在ksoap2android中有没有办法避免以字符串形式转义xml?我已经回顾了在soap请求的“body”标记中发送“fhateva”。也就是说,我考虑在正文中发送我们作为字符串提供的xml。 做这样的事情通常不是个好主意,但——有时这确实是做一些丑陋但资源高效的事情的最佳方式——fe。您的xml字符串解析、更改为可序列化和序列化似乎也不是很好 下面我介绍了三个类,它们是对SoapSerializationEnvelope、HttpTransportSE和KXmlSerializer的修改。其中两个只需要小的更改,可以通过继承类添加。但是需要包含在ksoap2-android-assembly-3.4.0-jar-with-dependencies中的类HttpTransportSE,因为方法“getPrefixes”。修改其他传输类取决于您:P 不幸的是,KXmlSerializer隐藏了所有不是XmlSerializer的东西,所以-这里有一个经过修改的完整类 这与您使用Android编程的类相同或几乎相同 我警告每个人,必须使用“那个东西”——它是真正的恐怖主义,并且试着只在维护成本方面使用它,这将由你或你的同事承担。第二个方面——KXmlSerializer相对来说比较旧,不经常更改 使用“那个东西”的示例:
TerroSerializationEnvelope=新的TerroserizationEnvelope(SoapEnvelope.VER11);
envelope.dotNet=true;
envelope.setOutputSoapObject(请求);
String src=“string1string1string1gstring1strings1tringstring1gst1ringba1se64binary”;
信封.setOutputString(src);
TerroHttpTransportSE androidHttpTransport=新的TerroHttpTransportSE(URL);
尝试
{
androidHttpTransport.debug=true;
调用(SOAP_操作,信封);
SoapObject响应=(SoapObject)信封.getResponse();
}
捕获(例外e)
{ ...
和修改类:
/**
* Copyright (c) 2006, James Seigel, Calgary, AB., Canada
* Copyright (c) 2003,2004, Stefan Haustein, Oberhausen, Rhld., Germany
*
* For full licences see links that are included in post above
**/
class TerroKXmlSerializer implements XmlSerializer {
// static final String UNDEFINED = ":";
// BEGIN android-added
/** size (in characters) for the write buffer */
private static final int WRITE_BUFFER_SIZE = 500;
// END android-added
// BEGIN android-changed
// (Guarantee that the writer is always buffered.)
private BufferedWriter writer;
// END android-changed
private boolean pending;
private int auto;
private int depth;
private String[] elementStack = new String[12];
//nsp/prefix/name
private int[] nspCounts = new int[4];
private String[] nspStack = new String[8];
//prefix/nsp; both empty are ""
private boolean[] indent = new boolean[4];
private boolean unicode;
private String encoding;
private final void check(boolean close) throws IOException {
if (!pending)
return;
depth++;
pending = false;
if (indent.length <= depth) {
boolean[] hlp = new boolean[depth + 4];
System.arraycopy(indent, 0, hlp, 0, depth);
indent = hlp;
}
indent[depth] = indent[depth - 1];
for (int i = nspCounts[depth - 1]; i < nspCounts[depth]; i++) {
writer.write(' ');
writer.write("xmlns");
if (!nspStack[i * 2].isEmpty()) {
writer.write(':');
writer.write(nspStack[i * 2]);
}
else if (getNamespace().isEmpty() && !nspStack[i * 2 + 1].isEmpty())
throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
writer.write("=\"");
writeEscaped(nspStack[i * 2 + 1], '"');
writer.write('"');
}
if (nspCounts.length <= depth + 1) {
int[] hlp = new int[depth + 8];
System.arraycopy(nspCounts, 0, hlp, 0, depth + 1);
nspCounts = hlp;
}
nspCounts[depth + 1] = nspCounts[depth];
// nspCounts[depth + 2] = nspCounts[depth];
writer.write(close ? " />" : ">");
}
private final void writeEscaped(String s, int quot) throws IOException {
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case '\n':
case '\r':
case '\t':
if(quot == -1)
writer.write(c);
else
writer.write("&#"+((int) c)+';');
break;
case '&' :
writer.write("&");
break;
case '>' :
writer.write(">");
break;
case '<' :
writer.write("<");
break;
default:
if (c == quot) {
writer.write(c == '"' ? """ : "'");
break;
}
// BEGIN android-changed: refuse to output invalid characters
// See http://www.w3.org/TR/REC-xml/#charsets for definition.
// No other Java XML writer we know of does this, but no Java
// XML reader we know of is able to parse the bad output we'd
// otherwise generate.
// Note: tab, newline, and carriage return have already been
// handled above.
boolean valid = (c >= 0x20 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xfffd);
if (!valid) {
reportInvalidCharacter(c);
}
if (unicode || c < 127) {
writer.write(c);
} else {
writer.write("&#" + ((int) c) + ";");
}
// END android-changed
}
}
}
// BEGIN android-added
private static void reportInvalidCharacter(char ch) {
throw new IllegalArgumentException("Illegal character (" + Integer.toHexString((int) ch) + ")");
}
// END android-added
/*
private final void writeIndent() throws IOException {
writer.write("\r\n");
for (int i = 0; i < depth; i++)
writer.write(' ');
}*/
public void docdecl(String dd) throws IOException {
writer.write("<!DOCTYPE");
writer.write(dd);
writer.write(">");
}
public void endDocument() throws IOException {
while (depth > 0) {
endTag(elementStack[depth * 3 - 3], elementStack[depth * 3 - 1]);
}
flush();
}
public void entityRef(String name) throws IOException {
check(false);
writer.write('&');
writer.write(name);
writer.write(';');
}
public boolean getFeature(String name) {
//return false;
return (
"http://xmlpull.org/v1/doc/features.html#indent-output"
.equals(
name))
? indent[depth]
: false;
}
public String getPrefix(String namespace, boolean create) {
try {
return getPrefix(namespace, false, create);
}
catch (IOException e) {
throw new RuntimeException(e.toString());
}
}
private final String getPrefix(
String namespace,
boolean includeDefault,
boolean create)
throws IOException {
for (int i = nspCounts[depth + 1] * 2 - 2;
i >= 0;
i -= 2) {
if (nspStack[i + 1].equals(namespace)
&& (includeDefault || !nspStack[i].isEmpty())) {
String cand = nspStack[i];
for (int j = i + 2;
j < nspCounts[depth + 1] * 2;
j++) {
if (nspStack[j].equals(cand)) {
cand = null;
break;
}
}
if (cand != null)
return cand;
}
}
if (!create)
return null;
String prefix;
if (namespace.isEmpty())
prefix = "";
else {
do {
prefix = "n" + (auto++);
for (int i = nspCounts[depth + 1] * 2 - 2;
i >= 0;
i -= 2) {
if (prefix.equals(nspStack[i])) {
prefix = null;
break;
}
}
}
while (prefix == null);
}
boolean p = pending;
pending = false;
setPrefix(prefix, namespace);
pending = p;
return prefix;
}
public Object getProperty(String name) {
throw new RuntimeException("Unsupported property");
}
public void ignorableWhitespace(String s)
throws IOException {
text(s);
}
public void setFeature(String name, boolean value) {
if ("http://xmlpull.org/v1/doc/features.html#indent-output"
.equals(name)) {
indent[depth] = value;
}
else
throw new RuntimeException("Unsupported Feature");
}
public void setProperty(String name, Object value) {
throw new RuntimeException(
"Unsupported Property:" + value);
}
public void setPrefix(String prefix, String namespace)
throws IOException {
check(false);
if (prefix == null)
prefix = "";
if (namespace == null)
namespace = "";
String defined = getPrefix(namespace, true, false);
// boil out if already defined
if (prefix.equals(defined))
return;
int pos = (nspCounts[depth + 1]++) << 1;
if (nspStack.length < pos + 1) {
String[] hlp = new String[nspStack.length + 16];
System.arraycopy(nspStack, 0, hlp, 0, pos);
nspStack = hlp;
}
nspStack[pos++] = prefix;
nspStack[pos] = namespace;
}
public void setOutput(Writer writer) {
// BEGIN android-changed
// Guarantee that the writer is always buffered.
if (writer instanceof BufferedWriter) {
this.writer = (BufferedWriter) writer;
} else {
this.writer = new BufferedWriter(writer, WRITE_BUFFER_SIZE);
}
// END android-changed
// elementStack = new String[12]; //nsp/prefix/name
//nspCounts = new int[4];
//nspStack = new String[8]; //prefix/nsp
//indent = new boolean[4];
nspCounts[0] = 2;
nspCounts[1] = 2;
nspStack[0] = "";
nspStack[1] = "";
nspStack[2] = "xml";
nspStack[3] = "http://www.w3.org/XML/1998/namespace";
pending = false;
auto = 0;
depth = 0;
unicode = false;
}
public void setOutput(OutputStream os, String encoding)
throws IOException {
if (os == null)
throw new IllegalArgumentException("os == null");
setOutput(
encoding == null
? new OutputStreamWriter(os)
: new OutputStreamWriter(os, encoding));
this.encoding = encoding;
if (encoding != null && encoding.toLowerCase(Locale.US).startsWith("utf")) {
unicode = true;
}
}
public void startDocument(String encoding, Boolean standalone) throws IOException {
writer.write("<?xml version='1.0' ");
if (encoding != null) {
this.encoding = encoding;
if (encoding.toLowerCase(Locale.US).startsWith("utf")) {
unicode = true;
}
}
if (this.encoding != null) {
writer.write("encoding='");
writer.write(this.encoding);
writer.write("' ");
}
if (standalone != null) {
writer.write("standalone='");
writer.write(
standalone.booleanValue() ? "yes" : "no");
writer.write("' ");
}
writer.write("?>");
}
public XmlSerializer startTag(String namespace, String name)
throws IOException {
check(false);
// if (namespace == null)
// namespace = "";
if (indent[depth]) {
writer.write("\r\n");
for (int i = 0; i < depth; i++)
writer.write(" ");
}
int esp = depth * 3;
if (elementStack.length < esp + 3) {
String[] hlp = new String[elementStack.length + 12];
System.arraycopy(elementStack, 0, hlp, 0, esp);
elementStack = hlp;
}
String prefix =
namespace == null
? ""
: getPrefix(namespace, true, true);
if (namespace != null && namespace.isEmpty()) {
for (int i = nspCounts[depth];
i < nspCounts[depth + 1];
i++) {
if (nspStack[i * 2].isEmpty() && !nspStack[i * 2 + 1].isEmpty()) {
throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
}
}
}
elementStack[esp++] = namespace;
elementStack[esp++] = prefix;
elementStack[esp] = name;
writer.write('<');
if (!prefix.isEmpty()) {
writer.write(prefix);
writer.write(':');
}
writer.write(name);
pending = true;
return this;
}
public XmlSerializer attribute(
String namespace,
String name,
String value)
throws IOException {
if (!pending)
throw new IllegalStateException("illegal position for attribute");
// int cnt = nspCounts[depth];
if (namespace == null)
namespace = "";
// depth--;
// pending = false;
String prefix =
namespace.isEmpty()
? ""
: getPrefix(namespace, false, true);
// pending = true;
// depth++;
/* if (cnt != nspCounts[depth]) {
writer.write(' ');
writer.write("xmlns");
if (nspStack[cnt * 2] != null) {
writer.write(':');
writer.write(nspStack[cnt * 2]);
}
writer.write("=\"");
writeEscaped(nspStack[cnt * 2 + 1], '"');
writer.write('"');
}
*/
writer.write(' ');
if (!prefix.isEmpty()) {
writer.write(prefix);
writer.write(':');
}
writer.write(name);
writer.write('=');
char q = value.indexOf('"') == -1 ? '"' : '\'';
writer.write(q);
writeEscaped(value, q);
writer.write(q);
return this;
}
public void flush() throws IOException {
check(false);
writer.flush();
}
/*
public void close() throws IOException {
check();
writer.close();
}
*/
public XmlSerializer endTag(String namespace, String name)
throws IOException {
if (!pending)
depth--;
// if (namespace == null)
// namespace = "";
if ((namespace == null
&& elementStack[depth * 3] != null)
|| (namespace != null
&& !namespace.equals(elementStack[depth * 3]))
|| !elementStack[depth * 3 + 2].equals(name))
throw new IllegalArgumentException("</{"+namespace+"}"+name+"> does not match start");
if (pending) {
check(true);
depth--;
}
else {
if (indent[depth + 1]) {
writer.write("\r\n");
for (int i = 0; i < depth; i++)
writer.write(" ");
}
writer.write("</");
String prefix = elementStack[depth * 3 + 1];
if (!prefix.isEmpty()) {
writer.write(prefix);
writer.write(':');
}
writer.write(name);
writer.write('>');
}
nspCounts[depth + 1] = nspCounts[depth];
return this;
}
public String getNamespace() {
return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 3];
}
public String getName() {
return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 1];
}
public int getDepth() {
return pending ? depth + 1 : depth;
}
//-------mmprog modify for terro serialize-----------------------------------
private boolean writeUnescaped = false;
public void setWriteUnescaped(boolean wu){
writeUnescaped = wu;
}
public XmlSerializer text(String text) throws IOException {
check(false);
indent[depth] = false;
if(!writeUnescaped){
writeEscaped(text, -1);
}else{
writer.write(text);
}
return this;
}
//-----------------------------------------------------------------------------
public XmlSerializer text(char[] text, int start, int len)
throws IOException {
text(new String(text, start, len));
return this;
}
public void cdsect(String data) throws IOException {
check(false);
// BEGIN android-changed: ]]> is not allowed within a CDATA,
// so break and start a new one when necessary.
data = data.replace("]]>", "]]]]><![CDATA[>");
char[] chars = data.toCharArray();
// We also aren't allowed any invalid characters.
for (char ch : chars) {
boolean valid = (ch >= 0x20 && ch <= 0xd7ff) ||
(ch == '\t' || ch == '\n' || ch == '\r') ||
(ch >= 0xe000 && ch <= 0xfffd);
if (!valid) {
reportInvalidCharacter(ch);
}
}
writer.write("<![CDATA[");
writer.write(chars, 0, chars.length);
writer.write("]]>");
// END android-changed
}
public void comment(String comment) throws IOException {
check(false);
writer.write("<!--");
writer.write(comment);
writer.write("-->");
}
public void processingInstruction(String pi)
throws IOException {
check(false);
writer.write("<?");
writer.write(pi);
writer.write("?>");
}
}
//-----------------------------------------------------------------------------------------
class TerroSerializationEnvelope extends SoapSerializationEnvelope {
private String myXmlString = null;
public TerroSerializationEnvelope(int version) {
super(version);
}
public void setOutputString(String o){
myXmlString = o;
}
@Override
public void writeBody(XmlSerializer writer) throws IOException {
if (encodingStyle != null) {
writer.attribute(env, "encodingStyle", encodingStyle);
}
if(myXmlString==null){
((Node) bodyOut).write(writer);
}else{
((TerroKXmlSerializer)writer).setWriteUnescaped(true);
writer.text(myXmlString);
((TerroKXmlSerializer)writer).setWriteUnescaped(false);
}
}
}
//-----------------------------------------------------------------------------------------
class TerroHttpTransportSE extends HttpTransportSE {
private int bufferLength = ServiceConnection.DEFAULT_BUFFER_SIZE;
private String myXmlVersionTag="";
public TerroHttpTransportSE(String url) {
super(url);
}
@Override
public void setXmlVersionTag(String tag) {
myXmlVersionTag = tag;
super.setXmlVersionTag(tag);
}
@Override
protected byte[] createRequestData(SoapEnvelope envelope, String encoding)
throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream(bufferLength);
byte result[] = null;
bos.write(myXmlVersionTag.getBytes());
XmlSerializer xw = new TerroKXmlSerializer();
final Iterator keysIter = getPrefixes().keySet().iterator();
xw.setOutput(bos, encoding);
while (keysIter.hasNext()) {
String key = (String) keysIter.next();
xw.setPrefix(key, (String) getPrefixes().get(key));
}
envelope.write(xw);
xw.flush();
bos.write('\r');
bos.write('\n');
bos.flush();
result = bos.toByteArray();
xw = null;
bos = null;
return result;
}
}
/**
*版权所有(c)2006,James Seigel,加拿大卡尔加里
*版权所有(c)20032004,Stefan Haustein,Oberhausen,Rhld.,德国
*
*有关完整的许可证,请参阅上面帖子中包含的链接
**/
类TerroKXmlSerializer实现XmlSerializer{
//静态最终字符串未定义=“:”;
//开始添加android
/**写入缓冲区的大小(以字符为单位)*/
私有静态最终整型写入缓冲区大小=500;
//最后添加了android
//开始更改android
//(确保写入程序始终处于缓冲状态。)
私有缓冲写入程序;
//结束android更改
私有布尔未决;
私家车;
私有整数深度;
私有字符串[]elementStack=新字符串[12];
//nsp/前缀/名称
私有整数[]nspCounts=新整数[4];
私有字符串[]nspStack=新字符串[8];
//前缀/nsp;两者均为空“”
私有布尔值[]缩进=新布尔值[4];
私有布尔unicode;
私有字符串编码;
私有最终无效检查(布尔关闭)引发IOException{
如果(!待定)
返回;
深度++;
未决=假;
如果(缩进长度):“>”;
}
private final void writeEscaped(字符串s,int quot)引发IOException{
对于(int i=0;i”:
作者:写(“”);
打破
CDATA中不允许使用“大小写”,
//所以,在必要的时候,中断并开始一个新的。
数据=数据。替换(“]]>”,“]]]>”;
char[]chars=data.toCharArray();
//我们也不允许使用任何无效字符。
for(char ch:chars){
boolean valid=(ch>=0x20&&ch=0xe000&&ch我认为您必须尝试不同的方法。ksoap2从头到尾都在使用org.xmlpull的接口XmlSerializer。XmlSerializer在内部转义字符。对象取自android的XmlPullParserFactory。保留它-节省您的时间。
/**
* Copyright (c) 2006, James Seigel, Calgary, AB., Canada
* Copyright (c) 2003,2004, Stefan Haustein, Oberhausen, Rhld., Germany
*
* For full licences see links that are included in post above
**/
class TerroKXmlSerializer implements XmlSerializer {
// static final String UNDEFINED = ":";
// BEGIN android-added
/** size (in characters) for the write buffer */
private static final int WRITE_BUFFER_SIZE = 500;
// END android-added
// BEGIN android-changed
// (Guarantee that the writer is always buffered.)
private BufferedWriter writer;
// END android-changed
private boolean pending;
private int auto;
private int depth;
private String[] elementStack = new String[12];
//nsp/prefix/name
private int[] nspCounts = new int[4];
private String[] nspStack = new String[8];
//prefix/nsp; both empty are ""
private boolean[] indent = new boolean[4];
private boolean unicode;
private String encoding;
private final void check(boolean close) throws IOException {
if (!pending)
return;
depth++;
pending = false;
if (indent.length <= depth) {
boolean[] hlp = new boolean[depth + 4];
System.arraycopy(indent, 0, hlp, 0, depth);
indent = hlp;
}
indent[depth] = indent[depth - 1];
for (int i = nspCounts[depth - 1]; i < nspCounts[depth]; i++) {
writer.write(' ');
writer.write("xmlns");
if (!nspStack[i * 2].isEmpty()) {
writer.write(':');
writer.write(nspStack[i * 2]);
}
else if (getNamespace().isEmpty() && !nspStack[i * 2 + 1].isEmpty())
throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
writer.write("=\"");
writeEscaped(nspStack[i * 2 + 1], '"');
writer.write('"');
}
if (nspCounts.length <= depth + 1) {
int[] hlp = new int[depth + 8];
System.arraycopy(nspCounts, 0, hlp, 0, depth + 1);
nspCounts = hlp;
}
nspCounts[depth + 1] = nspCounts[depth];
// nspCounts[depth + 2] = nspCounts[depth];
writer.write(close ? " />" : ">");
}
private final void writeEscaped(String s, int quot) throws IOException {
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case '\n':
case '\r':
case '\t':
if(quot == -1)
writer.write(c);
else
writer.write("&#"+((int) c)+';');
break;
case '&' :
writer.write("&");
break;
case '>' :
writer.write(">");
break;
case '<' :
writer.write("<");
break;
default:
if (c == quot) {
writer.write(c == '"' ? """ : "'");
break;
}
// BEGIN android-changed: refuse to output invalid characters
// See http://www.w3.org/TR/REC-xml/#charsets for definition.
// No other Java XML writer we know of does this, but no Java
// XML reader we know of is able to parse the bad output we'd
// otherwise generate.
// Note: tab, newline, and carriage return have already been
// handled above.
boolean valid = (c >= 0x20 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xfffd);
if (!valid) {
reportInvalidCharacter(c);
}
if (unicode || c < 127) {
writer.write(c);
} else {
writer.write("&#" + ((int) c) + ";");
}
// END android-changed
}
}
}
// BEGIN android-added
private static void reportInvalidCharacter(char ch) {
throw new IllegalArgumentException("Illegal character (" + Integer.toHexString((int) ch) + ")");
}
// END android-added
/*
private final void writeIndent() throws IOException {
writer.write("\r\n");
for (int i = 0; i < depth; i++)
writer.write(' ');
}*/
public void docdecl(String dd) throws IOException {
writer.write("<!DOCTYPE");
writer.write(dd);
writer.write(">");
}
public void endDocument() throws IOException {
while (depth > 0) {
endTag(elementStack[depth * 3 - 3], elementStack[depth * 3 - 1]);
}
flush();
}
public void entityRef(String name) throws IOException {
check(false);
writer.write('&');
writer.write(name);
writer.write(';');
}
public boolean getFeature(String name) {
//return false;
return (
"http://xmlpull.org/v1/doc/features.html#indent-output"
.equals(
name))
? indent[depth]
: false;
}
public String getPrefix(String namespace, boolean create) {
try {
return getPrefix(namespace, false, create);
}
catch (IOException e) {
throw new RuntimeException(e.toString());
}
}
private final String getPrefix(
String namespace,
boolean includeDefault,
boolean create)
throws IOException {
for (int i = nspCounts[depth + 1] * 2 - 2;
i >= 0;
i -= 2) {
if (nspStack[i + 1].equals(namespace)
&& (includeDefault || !nspStack[i].isEmpty())) {
String cand = nspStack[i];
for (int j = i + 2;
j < nspCounts[depth + 1] * 2;
j++) {
if (nspStack[j].equals(cand)) {
cand = null;
break;
}
}
if (cand != null)
return cand;
}
}
if (!create)
return null;
String prefix;
if (namespace.isEmpty())
prefix = "";
else {
do {
prefix = "n" + (auto++);
for (int i = nspCounts[depth + 1] * 2 - 2;
i >= 0;
i -= 2) {
if (prefix.equals(nspStack[i])) {
prefix = null;
break;
}
}
}
while (prefix == null);
}
boolean p = pending;
pending = false;
setPrefix(prefix, namespace);
pending = p;
return prefix;
}
public Object getProperty(String name) {
throw new RuntimeException("Unsupported property");
}
public void ignorableWhitespace(String s)
throws IOException {
text(s);
}
public void setFeature(String name, boolean value) {
if ("http://xmlpull.org/v1/doc/features.html#indent-output"
.equals(name)) {
indent[depth] = value;
}
else
throw new RuntimeException("Unsupported Feature");
}
public void setProperty(String name, Object value) {
throw new RuntimeException(
"Unsupported Property:" + value);
}
public void setPrefix(String prefix, String namespace)
throws IOException {
check(false);
if (prefix == null)
prefix = "";
if (namespace == null)
namespace = "";
String defined = getPrefix(namespace, true, false);
// boil out if already defined
if (prefix.equals(defined))
return;
int pos = (nspCounts[depth + 1]++) << 1;
if (nspStack.length < pos + 1) {
String[] hlp = new String[nspStack.length + 16];
System.arraycopy(nspStack, 0, hlp, 0, pos);
nspStack = hlp;
}
nspStack[pos++] = prefix;
nspStack[pos] = namespace;
}
public void setOutput(Writer writer) {
// BEGIN android-changed
// Guarantee that the writer is always buffered.
if (writer instanceof BufferedWriter) {
this.writer = (BufferedWriter) writer;
} else {
this.writer = new BufferedWriter(writer, WRITE_BUFFER_SIZE);
}
// END android-changed
// elementStack = new String[12]; //nsp/prefix/name
//nspCounts = new int[4];
//nspStack = new String[8]; //prefix/nsp
//indent = new boolean[4];
nspCounts[0] = 2;
nspCounts[1] = 2;
nspStack[0] = "";
nspStack[1] = "";
nspStack[2] = "xml";
nspStack[3] = "http://www.w3.org/XML/1998/namespace";
pending = false;
auto = 0;
depth = 0;
unicode = false;
}
public void setOutput(OutputStream os, String encoding)
throws IOException {
if (os == null)
throw new IllegalArgumentException("os == null");
setOutput(
encoding == null
? new OutputStreamWriter(os)
: new OutputStreamWriter(os, encoding));
this.encoding = encoding;
if (encoding != null && encoding.toLowerCase(Locale.US).startsWith("utf")) {
unicode = true;
}
}
public void startDocument(String encoding, Boolean standalone) throws IOException {
writer.write("<?xml version='1.0' ");
if (encoding != null) {
this.encoding = encoding;
if (encoding.toLowerCase(Locale.US).startsWith("utf")) {
unicode = true;
}
}
if (this.encoding != null) {
writer.write("encoding='");
writer.write(this.encoding);
writer.write("' ");
}
if (standalone != null) {
writer.write("standalone='");
writer.write(
standalone.booleanValue() ? "yes" : "no");
writer.write("' ");
}
writer.write("?>");
}
public XmlSerializer startTag(String namespace, String name)
throws IOException {
check(false);
// if (namespace == null)
// namespace = "";
if (indent[depth]) {
writer.write("\r\n");
for (int i = 0; i < depth; i++)
writer.write(" ");
}
int esp = depth * 3;
if (elementStack.length < esp + 3) {
String[] hlp = new String[elementStack.length + 12];
System.arraycopy(elementStack, 0, hlp, 0, esp);
elementStack = hlp;
}
String prefix =
namespace == null
? ""
: getPrefix(namespace, true, true);
if (namespace != null && namespace.isEmpty()) {
for (int i = nspCounts[depth];
i < nspCounts[depth + 1];
i++) {
if (nspStack[i * 2].isEmpty() && !nspStack[i * 2 + 1].isEmpty()) {
throw new IllegalStateException("Cannot set default namespace for elements in no namespace");
}
}
}
elementStack[esp++] = namespace;
elementStack[esp++] = prefix;
elementStack[esp] = name;
writer.write('<');
if (!prefix.isEmpty()) {
writer.write(prefix);
writer.write(':');
}
writer.write(name);
pending = true;
return this;
}
public XmlSerializer attribute(
String namespace,
String name,
String value)
throws IOException {
if (!pending)
throw new IllegalStateException("illegal position for attribute");
// int cnt = nspCounts[depth];
if (namespace == null)
namespace = "";
// depth--;
// pending = false;
String prefix =
namespace.isEmpty()
? ""
: getPrefix(namespace, false, true);
// pending = true;
// depth++;
/* if (cnt != nspCounts[depth]) {
writer.write(' ');
writer.write("xmlns");
if (nspStack[cnt * 2] != null) {
writer.write(':');
writer.write(nspStack[cnt * 2]);
}
writer.write("=\"");
writeEscaped(nspStack[cnt * 2 + 1], '"');
writer.write('"');
}
*/
writer.write(' ');
if (!prefix.isEmpty()) {
writer.write(prefix);
writer.write(':');
}
writer.write(name);
writer.write('=');
char q = value.indexOf('"') == -1 ? '"' : '\'';
writer.write(q);
writeEscaped(value, q);
writer.write(q);
return this;
}
public void flush() throws IOException {
check(false);
writer.flush();
}
/*
public void close() throws IOException {
check();
writer.close();
}
*/
public XmlSerializer endTag(String namespace, String name)
throws IOException {
if (!pending)
depth--;
// if (namespace == null)
// namespace = "";
if ((namespace == null
&& elementStack[depth * 3] != null)
|| (namespace != null
&& !namespace.equals(elementStack[depth * 3]))
|| !elementStack[depth * 3 + 2].equals(name))
throw new IllegalArgumentException("</{"+namespace+"}"+name+"> does not match start");
if (pending) {
check(true);
depth--;
}
else {
if (indent[depth + 1]) {
writer.write("\r\n");
for (int i = 0; i < depth; i++)
writer.write(" ");
}
writer.write("</");
String prefix = elementStack[depth * 3 + 1];
if (!prefix.isEmpty()) {
writer.write(prefix);
writer.write(':');
}
writer.write(name);
writer.write('>');
}
nspCounts[depth + 1] = nspCounts[depth];
return this;
}
public String getNamespace() {
return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 3];
}
public String getName() {
return getDepth() == 0 ? null : elementStack[getDepth() * 3 - 1];
}
public int getDepth() {
return pending ? depth + 1 : depth;
}
//-------mmprog modify for terro serialize-----------------------------------
private boolean writeUnescaped = false;
public void setWriteUnescaped(boolean wu){
writeUnescaped = wu;
}
public XmlSerializer text(String text) throws IOException {
check(false);
indent[depth] = false;
if(!writeUnescaped){
writeEscaped(text, -1);
}else{
writer.write(text);
}
return this;
}
//-----------------------------------------------------------------------------
public XmlSerializer text(char[] text, int start, int len)
throws IOException {
text(new String(text, start, len));
return this;
}
public void cdsect(String data) throws IOException {
check(false);
// BEGIN android-changed: ]]> is not allowed within a CDATA,
// so break and start a new one when necessary.
data = data.replace("]]>", "]]]]><![CDATA[>");
char[] chars = data.toCharArray();
// We also aren't allowed any invalid characters.
for (char ch : chars) {
boolean valid = (ch >= 0x20 && ch <= 0xd7ff) ||
(ch == '\t' || ch == '\n' || ch == '\r') ||
(ch >= 0xe000 && ch <= 0xfffd);
if (!valid) {
reportInvalidCharacter(ch);
}
}
writer.write("<![CDATA[");
writer.write(chars, 0, chars.length);
writer.write("]]>");
// END android-changed
}
public void comment(String comment) throws IOException {
check(false);
writer.write("<!--");
writer.write(comment);
writer.write("-->");
}
public void processingInstruction(String pi)
throws IOException {
check(false);
writer.write("<?");
writer.write(pi);
writer.write("?>");
}
}
//-----------------------------------------------------------------------------------------
class TerroSerializationEnvelope extends SoapSerializationEnvelope {
private String myXmlString = null;
public TerroSerializationEnvelope(int version) {
super(version);
}
public void setOutputString(String o){
myXmlString = o;
}
@Override
public void writeBody(XmlSerializer writer) throws IOException {
if (encodingStyle != null) {
writer.attribute(env, "encodingStyle", encodingStyle);
}
if(myXmlString==null){
((Node) bodyOut).write(writer);
}else{
((TerroKXmlSerializer)writer).setWriteUnescaped(true);
writer.text(myXmlString);
((TerroKXmlSerializer)writer).setWriteUnescaped(false);
}
}
}
//-----------------------------------------------------------------------------------------
class TerroHttpTransportSE extends HttpTransportSE {
private int bufferLength = ServiceConnection.DEFAULT_BUFFER_SIZE;
private String myXmlVersionTag="";
public TerroHttpTransportSE(String url) {
super(url);
}
@Override
public void setXmlVersionTag(String tag) {
myXmlVersionTag = tag;
super.setXmlVersionTag(tag);
}
@Override
protected byte[] createRequestData(SoapEnvelope envelope, String encoding)
throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream(bufferLength);
byte result[] = null;
bos.write(myXmlVersionTag.getBytes());
XmlSerializer xw = new TerroKXmlSerializer();
final Iterator keysIter = getPrefixes().keySet().iterator();
xw.setOutput(bos, encoding);
while (keysIter.hasNext()) {
String key = (String) keysIter.next();
xw.setPrefix(key, (String) getPrefixes().get(key));
}
envelope.write(xw);
xw.flush();
bos.write('\r');
bos.write('\n');
bos.flush();
result = bos.toByteArray();
xw = null;
bos = null;
return result;
}
}