Java中解析XML的问题

Java中解析XML的问题,java,xml,xml-parsing,document,Java,Xml,Xml Parsing,Document,解析XML文档时遇到了一些问题。出于某种原因,有些文本节点是我不希望它们出现的,因此我的测试变为红色。XML文件如下所示: PR1 一 二 DG1 三 ZBK 四 现在我有了这段代码,可以重现错误: DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builde

解析XML文档时遇到了一些问题。出于某种原因,有些文本节点是我不希望它们出现的,因此我的测试变为红色。XML文件如下所示:


PR1
一
二
DG1
三
ZBK
四
现在我有了这段代码,可以重现错误:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(TestHL7Helper.class.getResourceAsStream("TestHL7HelperInput.xml"));
Node root = doc.getFirstChild();
Node pr1 = root.getFirstChild();
检查根变量会产生
[RootNode:null]
,这似乎是正确的,但不知怎的,它会出错。
pr1
变量原来是一个文本节点
[#text:\n]
——但是为什么解析器认为新行和空格是一个文本节点呢?这难道不应该被忽视吗?我试着改变编码,但也没用。有什么想法吗


如果删除所有新行和空格,并将XML文档放在一行中,则一切正常…

您可以通过检查节点类型来解决此一般问题:

if (someNode instanceof Element) {
  // ...
}
这很容易形成循环的一部分,例如:

NodeList childNodes = root.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
  if (childNodes.item(i).getNodeType() == Node.ELEMENT) {
    Element childElement = (Element) childNodes.item(i);
    // ...
  }
}
NodeList childNodes=root.getChildNodes();
对于(int i=0;i

或者,在手动解析XML时,使用类似的方法来降低引入错误的可能性。找一个经过良好测试的库来为您完成这项工作

您可以通过检查节点的类型来解决此一般问题:

if (someNode instanceof Element) {
  // ...
}
这很容易形成循环的一部分,例如:

NodeList childNodes = root.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
  if (childNodes.item(i).getNodeType() == Node.ELEMENT) {
    Element childElement = (Element) childNodes.item(i);
    // ...
  }
}
NodeList childNodes=root.getChildNodes();
对于(int i=0;i

或者,在手动解析XML时,使用类似的方法来降低引入错误的可能性。找一个经过良好测试的库来为您完成这项工作

实际上,其他节点之间的所有文本都构成了文本节点本身。因此,如果使用
getFirstChild()
,还将检索这些文本节点

在您的情况下,所有非文本子节点都有一个唯一的名称,因此您可以使用以下方法分别获取它们:


一般来说,我不会依赖于XML文档中的位置,而是依赖于诸如标记名、属性或ID之类的内容。

实际上,其他节点之间的所有文本都构成了文本节点本身。因此,如果使用
getFirstChild()
,还将检索这些文本节点

在您的情况下,所有非文本子节点都有一个唯一的名称,因此您可以使用以下方法分别获取它们:


一般来说,我不会依赖于XML文档中的位置,而是依赖于诸如标记名、属性或ID之类的内容。

XML支持混合内容,这意味着元素可以同时具有文本和元素子节点。这是为了支持如下用例:

<text>I've bolded the <b>important</b> part.</text>
schema.xsd

如果创建的
schema.xsd
如下所示,那么演示代码将报告根元素有一个子节点

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
    <element name="RootNode">
        <complexType>
            <sequence>
                <element name="PR1" type="string"/>
            </sequence>
        </complexType>
    </element>
</schema>

XML支持混合内容,这意味着元素可以同时具有文本和元素子节点。这是为了支持如下用例:

<text>I've bolded the <b>important</b> part.</text>
schema.xsd

如果创建的
schema.xsd
如下所示,那么演示代码将报告根元素有一个子节点

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
    <element name="RootNode">
        <complexType>
            <sequence>
                <element name="PR1" type="string"/>
            </sequence>
        </complexType>
    </element>
</schema>

这是一个[Dom解析示例][1],可能会对您有所帮助。[1] :也许问题的标题应该更改。我仔细阅读了它,获得了一些关于混合内容和DOM解析的信息,并在那里得到了答案,但问题的标题并没有吸引我的第一眼。类似于“使用Java DOM解析混合内容的XML时出现问题”。下面是一个[DOM解析示例][1],可能会对您有所帮助。[1] :也许问题的标题应该更改。我仔细阅读了它,获得了一些关于混合内容和DOM解析的信息,并在那里得到了答案,但问题的标题并没有吸引我的第一眼。类似于“用JavaDOM解析混合内容的XML问题”。这是我考虑过的一个解决方案,但有点难看。必须有一些东西不能用所有这些if和else来填充我的代码,只是为了检查解析是否有问题。@如果你有唯一的名称,那么恶意更简单。或者,您可以考虑使用类似于生成专门用于读取与XSD/DTD匹配的XML文件的类。我同意@邓肯-使用现有的库来处理解析。我过去使用过JDOM,发现它简单直观,没有太多的学习曲线。我建议使用
someNode.getNodeType()==Node.ELEMENT
而不是
someNode instanceof ELEMENT
。我见过一些DOM实现,其中底层的
节点
impl类实现了多个接口(即
文档
元素
),并且
检查的
实例可能返回误报。@BlaiseDoughan很高兴知道,谢谢。事实上,我找到了一个关于这个问题的很好的链接:这是我考虑过的一个解决方案,但它有点丑陋。必须有一些东西不能用所有这些if和else来填充我的代码,只是为了检查解析是否有问题。@如果你有唯一的名称,那么恶意更简单。或者,您可以考虑使用类似于生成专门用于读取与XSD/DTD匹配的XML文件的类。我同意@邓肯-使用现有的库来处理解析。我过去使用过JDOM,发现它简单直观,没有太多的学习曲线。我建议使用
someNode.getNodeType()==Node.ELEMENT
而不是
someNode instanceof ELEMENT
。我见过一些DOM实现,其中底层的
节点
impl类实现了多个接口(即
文档
元素
),而
检查的
实例可能返回误报。@BlaiseDougha