0

我是网络服务的初学者,任何有经验的人都可以帮助我解决以下问题:

我正在编写一个试图从 OMIM RESTful Web 服务获取信息的客户端。我正在使用注册后提供的密钥 OMIM。( http://omim.org/help/api ) 我成功连接到客户端。同样使用 GET 方法,我可以将所需的数据提取到 DOM 文档中。此外,我可以成功地将整个 DOM 写入本地磁盘上的文件中。但是,我无法使用可用于 DOM 的标准解析函数来处理 DOM。

例如:我可以使用 NodeList nl=doc.getDocumentElement() 获取根节点并打印到控制台上。但是当我尝试打印根节点的第一个子节点时,它返回 null 而不是预期的子节点。

示例 XML 表单:webservices -> DOM -> 文件

    <?xml version="1.0" encoding="UTF-8" standalone="no"?><omim version="1.0">
    <clinicalSynopsisList>
    <clinicalSynopsis>
    <mimNumber>100070</mimNumber>
    <prefix>%</prefix>
    </clinicalSynopsis>
    </clinicalSynopsisList>
    </omim>

请在下面找到我的代码:

String path="http://api.omim.org:8000/api/clinicalSynopsis?mimNumber="+"100070"+"&include=clinicalSynopsis&format=xml&apiKey="+"<< xxxxx private key xxxxxxxxxx >> ";

                  URL url = new URL(path);

                  HttpURLConnection conn=(HttpURLConnection)url.openConnection();

                  conn.setRequestMethod("GET");

                  InputStream is = conn.getInputStream();

                  DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

                  Document doc = docBuilder.parse(is);

                  Source src= new DOMSource(doc);

                  File file = new File("d:/text.xml");

                  Result rs = new StreamResult(file);

                  TransformerFactory tmf = TransformerFactory.newInstance();

                  Transformer trnsfrmr = tmf.newTransformer();

                  trnsfrmr.transform(src, rs);

                  System.out.println("XML file is created successfully");

                  System.out.println("The root element is :: "+doc.getDocumentElement().getNodeName());


                  NodeList nl=doc.getDocumentElement().getChildNodes();

                  System.out.println("child nodelist length::"+nl.getLength());


                  System.out.println("First child node name :: "+doc.getDocumentElement().getFirstChild().getNodeName());

                  System.out.println("Last child node name :: "+doc.getDocumentElement().getLastChild().getNodeName());

我得到的输出:- XML 文件创建成功根元素是 :: omim child nodelist length::3 第一个子节点名称 :: #text 最后一个子节点名称 :: #text

在得到的输出中,根节点是“omim”,它有 3 个子节点。但在尝试打印第一个和最后一个子名称时返回 null。同样getParent()、getChild()、getSibling() 方法对我不起作用。

任何帮助将不胜感激。

谢谢,

4

2 回答 2

0

(我对biostar的回答很腼腆)我目前无法使用 OMIM API,但下面的 java 代码应该可以完成这项工作。我认为您的问题是您假设 XML 节点的第一个子节点是一个 ELEMENT,这是错误的,它似乎是一个包含回车的 TEXT 节点。

import java.net.URLEncoder;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class Biostar44705
    {
    private static final String API_KEY="XXXXXXXX"; 
    private DocumentBuilder builder;
    private Transformer echoTransformer=null;

    private Biostar44705()throws Exception
        {
        DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
        factory.setCoalescing(true);
        factory.setIgnoringComments(true);
        factory.setNamespaceAware(false);
        builder=factory.newDocumentBuilder();

        TransformerFactory trf=TransformerFactory.newInstance();
        this.echoTransformer =trf.newTransformer();
        this.echoTransformer .setOutputProperty(OutputKeys.INDENT, "yes");
        this.echoTransformer .setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        }
    void get(int omimId)throws Exception
        {
        String uri="http://api.omim.org:8000/api/clinicalSynopsis?mimNumber="+omimId+
                "&include=clinicalSynopsis&format=xml&apiKey="+
                URLEncoder.encode(API_KEY,"UTF-8");
        Document dom=builder.parse(uri);
        Element root=dom.getDocumentElement();
        if(root==null) return;
        for(Node n1=root.getFirstChild();n1!=null;n1=n1.getNextSibling())
            {
            if(n1.getNodeType()!=Node.ELEMENT_NODE) continue;
            echoTransformer.transform(new DOMSource(n1),new StreamResult(System.out));
            break;
            }
        }
public static void main(String[] args) throws Exception
    {
    new Biostar44705().get(100070);
    }
}
于 2012-05-11T16:41:37.070 回答
0

我发表了评论,然后我想我宁愿在答案中进一步解释。您应该问为什么root有 3 个子节点。只有一个孩子element-clinicalSynopsisList为什么是 3 个?第一个和最后一个孩子是clinicalSynopsisList. 您的节点内容被解释为MIXED,因为您没有模式或 DTD 来告诉omni只能包含元素的解析。如果你有,你可以告诉你的解析器忽略可忽略的空格,就像我在我的评论中提到的另一个 SO 问题中解释的那样。

自从我直接使用 DOM API 以来已经有一段时间了,但我不相信你可以要求它提供第一个子元素。相反,您可以使用 XPath(例如从这里开始,或者搜索 SO 或 google 以获取示例)来获取您的第一个子元素,或者只是使用 DOM API 遍历子节点并咨询它们的节点类型(您将忽略文本节点)

而且我还建议查看Apache CXF和JAXB等编组技术,这样您就不必使用从 Web 服务端点读取的“原始”XML。

于 2012-05-11T13:13:50.947 回答