关于DocumentBuilder.parse和InputStream返回null的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于4.jaxp----dom解析器(DocumentBuil
关于DocumentBuilder.parse和InputStream返回null的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于4. jaxp----dom 解析器(DocumentBuilderFactory、DocumentBuilder)、bufferedinputstream FileInputStream inputstream的比较、c# – StringBuilder还是XMLDocument?、c# – XDocument Root.Elements()返回null等相关知识的信息别忘了在本站进行查找喔。
本文目录一览:- DocumentBuilder.parse(InputStream)返回null(contentdocument返回null)
- 4. jaxp----dom 解析器(DocumentBuilderFactory、DocumentBuilder)
- bufferedinputstream FileInputStream inputstream的比较
- c# – StringBuilder还是XMLDocument?
- c# – XDocument Root.Elements()返回null
DocumentBuilder.parse(InputStream)返回null(contentdocument返回null)
我正在修复有关DocumentBuilder.parse的现有代码的错误。我有以下代码:
String theOutput; theOutput = response.encodeURL(prefix + "/include/sampleForConversion.jsp?" + request.getQueryString(); StreamSource xmlSource = new StreamSource(new URL(theOutput).openStream(), "http://sampleApps.net/static/dataDef1.1.dtd"); Document xmlDoc = dBuilder.parse(xmlSource.getInputStream());
我不明白为什么我得到xmlDoc的空值,尽管我具有Output和xmlSource变量的有效值。请帮忙。
谢谢!
答案1
小编典典流很可能已经正确解析,仅因为 xmlDoc.toString()
它将始终是"[#document:null]"
。这并不表示DOM树为空。请首先检查文档中是否有某些节点(子节点)。
如果DOM确实是空的,那么我首先将输入流的内容打印到控制台(可能xmlSource.getInputStream().toString()
已经返回了内容),以检查内容格式是否正确,请再次检查dtd文件是否可访问(浏览器)
),最后将XML文档和dtd转储到文件中,以检查XML内容是否有效。
嗯,等等,我以为第二个参数是DTD文件的URI,但是字符串是xml文档(public StreamSource(InputStreaminputStream, String systemId)
)的systemId 。也许是个问题-
StreamSource类将使用此URI来解析相对URI(例如DTD)。
4. jaxp----dom 解析器(DocumentBuilderFactory、DocumentBuilder)
1.DocumentBuilderFactory-- 解析器工厂(抽象类 javax.xml.parsers.DocumentBuilderFactory)
newInstance () 获取 DocumentBuilderFactory 的新实例。
newDocumentBuilder () 使用当前配置的参数创建一个新的 DocumentBuilder 实例。
2.DocumentBuilder-- 解析器(抽象类 javax.xml.parsers.DocumentBuilder)
parse(String uri)
将给定 URI 的内容解析为一个 XML 文档,并且返回一个新的 DOM Document 对象。(url 是相对路径 --- 项目)
- Document (接口,父接口 Node org.w3c.dom.Document)
- Node (接口 org.w3c.dom.Node)
3.Document (接口,父接口 Node org.w3c.dom.Document)
getElementsByTagName(String tagname)
返回文档中所有指定的标签名节点 (NodeList)
getElementById(String elementId)
返回具有带给定值的 ID 属性的 Element。
createElement(String tagName)
创建指定的节点(标签)。
createTextNode(String data)
创建给定指定字符串的 Text 节点。
4.NodeList (接口)
jdk 文档介绍:NodeList 接口提供对节点的有序集合的抽象,没有定义或约束如何实现此集合。DOM 中的 NodeList 对象是活动的
getLength () 列表中的节点数。
item (int index) 返回集合中的第 index 个项(Node 类型)。
5.Node (接口 org.w3c.dom.Node) 常用方法
- 获取
getFirstChild () 此节点的第一个子节点。
getLastChild () 此节点的最后一个节点。
getParentNode () 此节点的父节点。
getChildNodes () 包含此节点的所有子节点的 NodeList。
getNextSibling () 直接在此节点之后的节点。
getNodeValue () 此节点的值,取决于其类型;
getPreviousSibling () 直接在此节点之前的节点。
getTextContent () 此属性返回此节点及其后代的文本内容。
- 添加
appendChild (Node newChild) 将节点 newChild 添加到此节点的子节点列表的末尾。
insertBefore (Node newChild, Node refChild) 在现有子节点 refChild 之前插入节点 newChild。
- 删除
removeChild (Node oldChild) 从子节点列表中移除 oldChild 所指示的子节点,并将其返回。
- 修改
replaceChild (Node newChild, Node oldChild) 将子节点列表中的子节点 oldChild 替换为 newChild,并返回 oldChild 节点。
setNodeValue (String nodeValue) 此节点的值,取决于其类型;
setTextContent (String textContent) 此属性返回此节点及其后代的文本内容。
- 判断
isEqualNode (Node arg) 测试两个节点是否相等
xml 文件
<?xml version="1.0" encoding="uft-8"?>
<!DOCTYPE persion SYSTEM "NewFile1.dtd">
<persion ID="persion">
<name ID="name1">张三</name>
<name ID="name2">zhangsan</name>
<age ID="age">18</age>
<sex ID="sex">男</sex>
</persion>
java 代码(根据标签名,查询标签里面的文本)
public class Demo1 {
public static void main(String[] args) throws Exception {
//查询标签名为name中的文本
selText("name");
} //查询
public static void selText(String strname) throws ParserConfigurationException, SAXException, IOException {
//实例化解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
//根据解析器工厂实例化解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
//获取xml的全部节点(根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象)
Document document = builder.parse("src/NewFile1.xml");
//根据标签名获取
NodeList list = document.getElementsByTagName(strname);
for(int i = 0 ; i<list.getLength() ; i++) {
//获取每一个name节点
Node name = list.item(i);
//获取每个name节点里面的文本
String nametext = name.getTextContent();
//输出文本
System.out.println(nametext);
}
}
}
结果
在我们使用增删改的时候,我们改动的都是内存中的数据节点,想要改动硬盘上面的数据节点,我们需要更新 xml 文本,下面是更新文本的一些类和方法
注意:我们的格式要是 utf-8,不然我们更新后中文会出现乱码的哦!(gbk 和 utf-16 不能写)
TransformerFactory (抽象类 javax.xml.transform ,TransformerFactory 实例可用于创建 Transformer
和 Templates
对象)
一些方法
newInstance () 创建 TransformerFactory 实例
newTransformer () 创建 Transformer 实例
Transformer(抽象类,此抽象类的实例能够将源树转换为结果树。javax.xml.transform)
transform (Source xmlSource, Result outputTarget) 将 XML Source
转换为 Result
。
例如:transformer.transform (new DOMSource (document), new StreamResult ("src/NewFile1.xml"));
- Source 接口 实现类之一 DOMSource
- Result 接口 实现类之一 StreamResult
添加节点(标签):在最后一个 name 标签里面添加新标签
代码如下:
public class Demo2 {
public static void main(String[] args) throws Exception {
//实例化解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
//实例化解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
//获取整个文档的节点对象
Document document = builder.parse("src/NewFile1.xml");
//创建一个标签
Element newelement = document.createElement("newelement");
//创建文本
Text text = document.createTextNode("新添加的标签");
//把文本添加到新创建的标签里面
newelement.appendChild(text);
//获取所有的name标签
NodeList list = document.getElementsByTagName("name");
//获取最后一个name标签
Node node = list.item(list.getLength()-1);
//在最后一个name标签里面添加一个子标签(newelement)
node.appendChild(newelement);
//因为我们处理的都是内存中的数据,不会影响到硬盘上面的数据,所以我们要把我们处理后的数据重新存储到硬盘上。
//更新xml文件(增删改都需要更新xml文件)
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/NewFile1.xml"));
}
}
xml 更新后(我们可以发现添加成功了,但是格式看着很不爽)
<?xml version="1.0" encoding="utf-8" standalone="no"?><persion ID="persion">
<name ID="name1">张三</name>
<name ID="name2">zhangsan<newelement>新添加的标签</newelement></name>
<age ID="age">18</age>
<sex ID="sex">男</sex>
</persion>
删除节点:删除上面添加的标签 (下面这个方法只能删除一个目标文件)
public class Demo3 {
public static void main(String[] args) throws Exception {
//实例化解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
//实例化解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
//获取xml文档(根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象)
Document document = builder.parse("src/NewFile1.xml");
//获取全部的目标节点对象(标签)
NodeList list = document.getElementsByTagName("newelement");
//获取NodeList集合中的一个目标节点
Node node = list.item(0);
//获取目标节点的父节点
Node faterNode = node.getParentNode();
//根据父节点删除父节点中的子节点(目标节点),如果要一次删除多个,那么需要使用循环
faterNode.removeChild(node);
//更新xml文档
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/NewFile1.xml"));
}
}
<?xml version="1.0" encoding="utf-8" standalone="no"?><persion ID="persion">
<name ID="name1">张三</name>
<name ID="name2">zhangsan</name>
<age ID="age">18</age>
<sex ID="sex">男</sex>
</persion>
修改:把标签名为 sex 的里面的文本修改
public class Demo4 {
public static void main(String[] args) throws Exception {
//实例化解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
//实例化解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
//获取整个文档的节点对象
Document document = builder.parse("src/NewFile1.xml");
//获取要修改的全部节点(NodeList集合)
NodeList list = document.getElementsByTagName("sex");
//获取目标节点的父节点
//循环NodeList集合,修改指定的全部目标节点(标签)中的文本
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
node.setTextContent("女");
}
//更新xml文档
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/NewFile1.xml"));
}
}
<?xml version="1.0" encoding="utf-8" standalone="no"?><persion ID="persion">
<name ID="name1">张三</name>
<name ID="name2">zhangsan</name>
<age ID="age">18</age>
<sex ID="sex">女</sex>
</persion>
bufferedinputstream FileInputStream inputstream的比较
BufferedInputStream类相比InputStream类,提高了输入效率,增加了输入缓冲区的功能
不带缓冲的操作,每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低
带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多
InputStream流是指将字节序列从外设或外存传递到应用程序的流
BufferedInputStream流是指读取数据时,数据首先保存进入缓冲区,其后的操作直接在缓冲区中完成。
继承关系是这样的:
java.lang.Object
Java.io.InputStrean
Java.io.FilterInputStream
Java.io.BufferedInputStream
FileInputStream是字节流,BufferedInputStream是字节缓冲流,使用BufferedInputStream读资源比FileInputStream读取资源的效率高(BufferedInputStream的read方法会读取尽可能多的字节),且FileInputStream对象的read方法会出现阻塞;
BufferedInputStream比FileInputStream多了一个缓冲区,执行read时先从缓冲区读取,当缓冲区数据读完时再把缓冲区填满。
当每次读取的数据量很小时,FileInputStream每次都是从硬盘读入,而BufferedInputStream大部分是从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此BufferedInputStream效率高。
BufferedInputStream的默认缓冲区大小是8192字节。当每次读取数据量接近或远超这个值时,两者效率就没有明显差别了。
c# – StringBuilder还是XMLDocument?
我编写了一个控制台应用程序来从Web服务器获取一些信息,将其转换为XML并保存.我手动创建了XML(使用StringBuilder追加字符串).因为XML可能非常大,就内存而言,使用StringBuilder或XMLDocument类等更好吗?
确切地说,我的问题是,如果XML就像10mb文本,那么使用StringBuilder.append(“”)或System.XML命名空间的内存效率是多少?
我认为更有效的方法是使用StringBuilder,但在每次迭代后将XML保存到HD上的文件并清除stringbuilder对象.任何意见?
提前致谢.
c# – XDocument Root.Elements()返回null
这里是xml的一个示例:
<?xml version="1.0" encoding="UTF-8"?> <TestRun id="2ece436d-907d-4f59-9c81-0544b2f4f7cd" name="redacted" runUser="redacted" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010"> <TestSettings name="Default Test Settings" id="e00bb4af-1518-4b40-9905-19fa7b190f68"> ... </TestSettings> <Times creation="2015-02-18T11:47:02.7188640-05:00" queuing="2015-02-18T11:47:03.1819103-05:00" start="2015-02-18T11:47:03.2819203-05:00" finish="2015-02-18T11:47:05.5571478-05:00" /> <ResultSummary outcome="Failed"> <Counters total="74" executed="74" passed="73" error="0" Failed="1" timeout="0" aborted="0" inconclusive="0" passedButRunAborted="0" notRunnable="0" notExecuted="0" disconnected="0" warning="0" completed="0" inProgress="0" pending="0" /> </ResultSummary>
我想要检索< ResultSummary>的结果,但是对xml.Root的所有Element()和Elements()调用都返回null.
var xml = XDocument.Load(resultFile); var outcome = xml.Root .Element("TestRun") .Element("ResultSummary") .Attribute("outcome") .Value;
我尝试添加像this answer中的命名空间,但我仍然得到相同的结果:
var xml = XDocument.Load(resultFile); XNamespace ns = "http://microsoft.com/schemas/VisualStudio/TeamTest/2010"; var outcome = xml.Root .Element(ns + "TestRun") .Element("ResultSummary") .Attribute("outcome") .Value;
另外,我不确定Root是否应该返回< TestRun>我是否尝试过运行xml.Root.Element(“ResultSummary”),我仍然得到null.
我该如何阅读这个xml文件?
解决方法
并且,为了从本地名称和命名空间获取对象,您可以使用XName.Get(string,string)方法:
因此,将代码更改为:
string ns = "http://microsoft.com/schemas/VisualStudio/TeamTest/2010"; var outcome = xml.Root .Element(XName.Get("ResultSummary",ns)) .Attribute("outcome") .Value;
结果是:失败
关于DocumentBuilder.parse和InputStream返回null的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于4. jaxp----dom 解析器(DocumentBuilderFactory、DocumentBuilder)、bufferedinputstream FileInputStream inputstream的比较、c# – StringBuilder还是XMLDocument?、c# – XDocument Root.Elements()返回null的相关知识,请在本站寻找。
本文标签: