新手使用android的XML(DOM)解析问题,指定路径XML如何读取

新手使用android的XML(DOM)解析问题,指定路径XML如何读取,第1张

一、在Android应用中的XML文件来源
1、本地xml文件
本地XML文件可以放在应用根目录assets文件夹、res/xml、res/raw、SDcard卡、应用的data目录等;
除res/xml可直接通过getXml(int id)获取XML文档,返回一个解析器对象(XmlResourceParer:XmlResourceParer是XmlPullParser的子类),其它位置情况都可以获取XML文档,返回一个Inputstream对象,进行读取数据,获取方法分别如下:
a在res/xml目录下(推荐使用):
[java] view plaincopy
XmlResourceParser xmlParser = thisgetResources()getXml(RxmlXXX);
b在res/xml、res/raw目录下:
[java] view plaincopy
InputStream inputStream = thisgetResources()openRawResource(RxmlXXX);
c在assets文件夹下(本人测试发现通过此方法获取的XML文档不能带有首行:<xml version="10" encoding="utf-8">,否则解析报错,具体原因未查明,知道原因请回复交流):
[java] view plaincopy
InputStream inputStream = getResources()getAssets()open(fileName);
d在应用指定目录下(SDcard,应用data目录等):
[java] view plaincopy
// path路径根据实际项目修改,此次获取SDcard根目录
String path = EnvironmentgetExternalStorageDirectory()toString();
File xmlFlie = new File(path+fileName);
InputStream inputStream = new FileInputStream(xmlFlie);
2、通过url得到的xml文件
很多时候需要解析xml文件都用于客户端与服务器之间的数据交互,比如解析google天气预报信息,或自己项目内定的一些XML数据结构,其中通过URL,使用Default>我可能表达的不是很清楚,那就拿个具体的例子来说明吧
比如说,在Activity中我们需要用到一个ProgressBar控件,我们一般先在layout下的mainxml中进行配置
Xml代码
<ProgressBar
android:id="@+id/pb1"
android:layout_width="fill_parent"
android:layout_height="20dip"
<span style="color: #ff0000;"> android:indeterminateOnly="false"</span>
android:layout_gravity="center_vertical"
android:progressDrawable="@android:drawable/progress_horizontal"
android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal"
android:minHeight="20dip"
android:maxHeight="20dip"
/>
我们看 android:indeterminateOnly="false" 这行代码的
一般我们如果要将在代码中创建一个ProgressBar,但是不通过配置文件得到。
代码如下:
Java代码
ProgressBar mProgressBar=new ProgressBar(context);

<span style="color: #ff0000;">mProgressBarsetIndeterminate(false); </span>
mProgressBarsetProgressDrawable(getResources()getDrawable
(androidRdrawableprogress_horizontal));

mProgressBarsetIndeterminateDrawable(getResources()getDrawable
(androidRdrawableprogress_indeterminate_horizontal));

本来我们是希望创建一个普通的能显示进度的横条ProgressBar
但是我们发现progressBar中的进度无法更新。
我们来看进度更新的源代码setProgress():
Java代码
@androidviewRemotableViewMethod
synchronized void setProgress(int progress, boolean fromUser) {
<span style="color: #ff0000;"> if (mIndeterminate) {
return;
}</span>
if (progress < 0) {
progress = 0;
}
if (progress > mMax) {
progress = mMax;
}
if (progress != mProgress) {
mProgress = progress;
refreshProgress(Ridprogress, mProgress, fromUser);
}
}
关键是: if (mIndeterminate) { return; }
原来mIndeterminate 的值为true的话,函数直接返回了,也就是我们不能设置progressBar的进度(mProgress)
现在我们的任务是将mIndeterminate 属性设置为false
但是我们发现 mProgressBarsetIndeterminate(false); 这行代码并没有设置mIndeterminate 属性为false
我们看ProgressBar中的源代码:
Java代码
@androidviewRemotableViewMethod
public synchronized void setIndeterminate(boolean indeterminate) {
<span style="color: #ff0000;"> if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) {</span>
mIndeterminate = indeterminate;

if (indeterminate) {
// swap between indeterminate and regular backgrounds
mCurrentDrawable = mIndeterminateDrawable;
startAnimation();
} else {
mCurrentDrawable = mProgressDrawable;
stopAnimation();
}
}
}
看这行代码: if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) {
我们发现当mOnlyIndeterminate 和mIndeterminate 之前都为true时,我们并不能将mIndeterminate 从true改变为false
google后,有人通过反射机制将ProgressBar中的mOnlyIndeterminate 设置为false(具体请看:关于使用代码来创建ProgressBar )
我现在我就在想 既然 ProgressBar中的mOnlyIndeterminate 和mIndeterminate属性都是private,而且都不能通过get和set方法来对其进行 *** 作,那么 android 通过在XML中配置的控件属性,是怎么被转换成真正的java类呢?
求大神解惑!
问题补充
over140 写道
你应该看一下他源码里关于这个的构造函数部分的代码,注意父类里面可能也有代码,他并不是转换成java类,只是读取从XML属性读取想要的参数。
你指的是ProgressBar类中的构造函数吗? 我之前就仔细看了这些东西
ProgressBar中构造函数源码:
Java代码
/
Create a new progress bar with range 0100 and initial progress of 0
@param context the application environment
/
public ProgressBar(Context context) {
this(context, null);
}

public ProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, comandroidinternalRattrprogressBarStyle);
}

public ProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mUiThreadId = ThreadcurrentThread()getId();
initProgressBar();

TypedArray a =
contextobtainStyledAttributes(attrs, RstyleableProgressBar, defStyle, 0);

mNoInvalidate = true;

Drawable drawable = agetDrawable(RstyleableProgressBar_progressDrawable);
if (drawable != null) {
drawable = tileify(drawable, false);
setProgressDrawable(drawable);
}
mDuration = agetInt(RstyleableProgressBar_indeterminateDuration, mDuration);

mMinWidth = agetDimensionPixelSize(RstyleableProgressBar_minWidth, mMinWidth);
mMaxWidth = agetDimensionPixelSize(RstyleableProgressBar_maxWidth, mMaxWidth);
mMinHeight = agetDimensionPixelSize(RstyleableProgressBar_minHeight, mMinHeight);
mMaxHeight = agetDimensionPixelSize(RstyleableProgressBar_maxHeight, mMaxHeight);

mBehavior = agetInt(RstyleableProgressBar_indeterminateBehavior, mBehavior);

final int resID = agetResourceId(
comandroidinternalRstyleableProgressBar_interpolator,
androidRanimlinear_interpolator); // default to linear interpolator
if (resID > 0) {
setInterpolator(context, resID);
}

setMax(agetInt(RstyleableProgressBar_max, mMax));

setProgress(agetInt(RstyleableProgressBar_progress, mProgress));

setSecondaryProgress(
agetInt(RstyleableProgressBar_secondaryProgress, mSecondaryProgress));

drawable = agetDrawable(RstyleableProgressBar_indeterminateDrawable);
if (drawable != null) {
drawable = tileifyIndeterminate(drawable);
setIndeterminateDrawable(drawable);
}

mOnlyIndeterminate = agetBoolean(
RstyleableProgressBar_indeterminateOnly, mOnlyIndeterminate);

mNoInvalidate = false;

setIndeterminate(mOnlyIndeterminate || agetBoolean(
RstyleableProgressBar_indeterminate, mIndeterminate));

arecycle();
}
看以上代码,发现ProgressBar类并没有使用其父类的构造方法, 它的三个构造方法最终都需要进入到第三个构造方法内,
再看这一句
Java代码
initProgressBar();
其中具体源码如下:
Java代码
private void initProgressBar() {
mMax = 100;
mProgress = 0;
mSecondaryProgress = 0;
mIndeterminate = false;
mOnlyIndeterminate = false;
mDuration = 4000;
mBehavior = AlphaAnimationRESTART;
mMinWidth = 24;
mMaxWidth = 48;
mMinHeight = 24;
mMaxHeight = 48;
}

看 这两句:
Java代码
mIndeterminate = false;
mOnlyIndeterminate = false;

奇怪 在这个初始化ProgressBar的过程中,明明将mIndeterminate和mOnlyIndeterminate属性设置为false
但是我们初始化后的进度条,显示后同样是不会进度的(图如下)
也就是说 mIndeterminate属性依然是true(具体请看ProgressBar中的setProgress()方法)
继续看构造方法中的其他内容时,发现关键所在:
Java代码
mOnlyIndeterminate = agetBoolean(
RstyleableProgressBar_indeterminateOnly, mOnlyIndeterminate);

mNoInvalidate = false;

setIndeterminate(mOnlyIndeterminate || agetBoolean(
RstyleableProgressBar_indeterminate, mIndeterminate));
这两句将mOnlydeterminate和mIndeterminate属性都设置为true,
看到这里,发现这两句都用到 a 这个对象,a 具体是什么呢?

Java代码
TypedArray a =
contextobtainStyledAttributes(attrs, RstyleableProgressBar, defStyle, 0);

那我们能不能通过改变传入 构造函数 的参数 来使 a 发生相应的变化,进而使mOnlyIndeterminate和mIndeterminate属性设置为 true 呢?
再往下深入,发现看的我那是一头雾水,完全找不到方向,所以只得放弃这个猜想。
到最后,我发现 如果要通过正常的java访问机制(当然排除使用反射机制),来 *** 作mOnlyIndeterminate和mIndeterminate属性是不可能的,
你说: 他并不是转换成java类,只是读取从XML属性读取想要的参数。
我们一般是通过findViewById()来根据layout中的XML文件设置的控件属性得到 具体的View控件对象(关于转换成java类,我错了,其实我想说的是怎么得到的这个对象),
这个过程是不是也是通过反射机制来完成的?假如是的话,能给我提供些具体过程的资料呢?

给你个思路
首先 递归遍历所有节点
然后 去每个节点里 找有没有 URL这个 属性
xmlDocSelectSingleNode(yourXmlPath)Attributes["URL"]

根据谬结论WS的原始数据包是被绑定在以2进制的VS方程中的一个连接原,也就是说想要获取这2进制单位的一个片段所携带的信息就必须按终端服务器所发送的信息源LUIX地址在未传达到接收端口时截取信息片段,分析XML的2进制信息码,但是现在主流的XML2进制信息码是由BK加密的片段,它不同与以往的加密方法,它是把信息终端发送的并携码排序并由终端分配VNA排列码,但是并不等同于数字加密根据不同的进制解密会映射不同的XML2进制信息码,目前并没有跟好的解密方法我帮你分析了一下你的执行域名,它的TC请求并非被绑定在JAXB那么你认为请求ws的response被映射成了一个java类的想法多少也有那么一点搞笑先来看你XMLNS的带链索引是TestClass由此可见它的这个WS的执行端口肯定不会被绑定在JAVA上最后这个执行端口所执行索引的XML数据真的很难被截取,所以建议你从接收端口接收信息密码源后再进行截取,一来降低风险,二来不必考虑BK的加密

<%
'ASP中的VBScript并不是VB,不过应该区别不大
‘定义变量
Dim oXml
Dim arrText, arrValue, sFGF
sFGF = "$$"
’创建XMLDOM对象
Set oXml = ServerCreateObject("MicrosoftXMLDOM")
‘设置异步读取文件
oXmlasync=False
’读取文件
oXmlload ServerMapPath("aulxml")
‘设置变量 节点类型的
Dim oNodes, oNode
’得到节点集合放入oNodes变量中
‘ SelectNodes()方法接受一个XPath参数可以搜索到你想要的节点集合
‘这里的 XPath是 "//screen/list/item"
Set oNodes = oXmldocumentElementSelectNodes("//screen/list/item")
‘迭代
For Each oNode In oNodes
’字符串拼接,因为VBScript Array没push()方法
arrText = arrText & oNodegetAttributeNode("labelText")nodeValue & sFGF
arrValue = arrValue & oNodegetAttributeNode("value")nodeValue & sFGF
Next
' 去掉最后的分隔符后再用Split()将字符串转换为数组得到结果
If arrText <> "" Then
arrText = Mid(arrText, 1, Len(arrText)-Len(sFGF))
arrText = Split(arrText, sFGF)
End If
If arrValue <> "" Then
arrValue = Mid(arrValue, 1, Len(arrValue)-Len(sFGF))
arrValue = Split(arrValue, sFGF)
End if
Set oNodes = Nothing
Set oXml = Nothing
' arrText, arrValue 就是结果了
‘ 输出一下测试
ResponseWrite arrValue(0)
' 上面的是ASP服务器端读取xml的代码。给你参考
%>

可以用javascript读取xml数据
实例如下:
首先:xml文件(treexml)内容如下:
<xml version="10" encoding="gb2312">
<treeview>
<tree id="p1">
<text>山东省</text>
<target>_blank</target>
<title>省份</title>
<link></link>
<tree id="p1-1">
<text>威海市</text>
<target>_blank</target>
<title>城市</title>
<link></link>
</tree>
<tree id="p1-2">
<text>烟台市</text>
<target>_blank</target>
<title>城市</title>
<link></link>
<node id="p1-2-1">
<text>长夼村</text>
<target>_blank</target>
<title>乡镇</title>
<link>>function stringToXML(xmlData) {
if (windowActiveXObject) {
//for IE
xmlDoc=new ActiveXObject("MicrosoftXMLDOM");
xmlDocasync="false";
xmlDocloadXML(xmlData);
return xmlDoc;
}
else if (documentimplementation && documentimplementationcreateDocument) {
//for Mozila
parser=new DOMParser();
xmlDoc=parserparseFromString(xmlData,"text/xml");
return xmlDoc;
}
}
var xmlObj = stringToXML(
['<xml version="10" encoding="utf-8">',
'<msg>',
'<list lrc_url="tinglrc" >',
'<u u="tingmp3" />',
'</list>',
'</msg>']join('')
);
alert(xmlObjxml); //打印xml代码
alert(xmlObjdocumentElementtagName); //根元素标签名
//全百度仅此一家,你不快点结案就太对不起我了~~
//哥哥给你google,看了不少英文才拼出这兼容IE和火狐浏览器的代码


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13382289.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-25
下一篇 2023-07-25

发表评论

登录后才能评论

评论列表(0条)

保存