Пространство имен XML получает проблемы для анализа файла в XPath + Java - PullRequest
1 голос
/ 10 января 2012

У меня также есть XML

<?xml version="1.0" encoding="UTF-8"?>
<QDTM_IN300301QD ITSVersion="XML_1.0" xmlns="urn:hl7-org:v3"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:hl7-org:v3 QDTM_IN300401QD.xsd ">

    <controlActEvent classCode="CACT" moodCode="EVN">
        <code code="QDTM_TE300401QD">
        </code>
        <statusCode code="Active" />
        <subject contextConductionInd="true" contextControlCode="ON"
            typeCode="SUBJ">
            <registrationEvent classCode="REG" moodCode="EVN">
                <statusCode code="token" />
                <subject contextControlCode="AN" typeCode="SBJ">
                    <testCodeIdentifier classCode="ROL">
                        <playingTestCodeDetails classCode="ENT"
                            determinerCode="INSTANCE">
                            <code code="6399Z" codeSystemName="QTIM" codeSystemVersion="Updated">
                                <originalText><![CDATA[CBC (includes Differential and Platelets)]]></originalText>
                                <translation codeSystemName="DOSCATALOGNAMEHTMLENABLED">
                                    <originalText><![CDATA[CBC (includes Differential and Platelets)]]></originalText>
                                </translation>
                            </code>
                        </playingTestCodeDetails>
                    </testCodeIdentifier>
                </subject>
            </registrationEvent>
        </subject>
    </controlActEvent>
</QDTM_IN300301QD>

КОД JAVA:

package com.parse;

import java.io.IOException;
import java.util.Iterator;

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;


public class ParseXPath {

    public String parseXML(String fileName) {
            fileName = "D://projects//Draft.xml";
            DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
            domFactory.setNamespaceAware(true); 
            DocumentBuilder builder;
            Document doc;
            try {

                builder = domFactory.newDocumentBuilder();
                doc = builder.parse(fileName);
                XPath xpath = XPathFactory.newInstance().newXPath();
                xpath.setNamespaceContext(new NamespaceContext(){public String getNamespaceURI(String prefix) {
                    return "urn:hl7-org:v3";
                }

                public String getPrefix(String namespaceURI) {
                    return null; // we are not using this.
                }

                public Iterator getPrefixes(String namespaceURI) {
                    return null; // we are not using this.
                }
                });

                String expr="//QDTM_IN300401QD/controlActEvent/subject/registrationEvent/subject/testCodeIdentifier/playingTestCodeDetails/code/translation[@codeSystemName='DOSCATALOGNAMEHTMLENABLED']/originalText/text()";

                String result = xpath.evaluate(expr, doc);
                System.out.println("Result -->  "+result); 
                return result;
            } catch (ParserConfigurationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            catch (SAXException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (XPathExpressionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return fileName;




         public static void main(String[] args) 
     throws ParserConfigurationException, SAXException, 
      IOException, XPathExpressionException {
         ParseBUXpath p = new ParseBUXpath();
         p.parseRelatedTestXML("test");



      }

}

Я сталкиваюсь с этой проблемой в пространстве имен XML.Когда xml имеет "xmlns =" ​​urn: hl7-org: v3 ", запрос xpath не получает мне данных. Для подавления этого я написал код в Java и удалил строку из XML.Мне нужно проанализировать XML и получить данные, не удаляя часть пространства имен из XML. Это проблема, связанная с xsd или не упоминается xsd?

Ответы [ 2 ]

1 голос
/ 10 января 2012

Вам необходимо включить пространство имен в выражение, пространство имен можно заменить на «префикс», выполняющий функцию поиска для полного пространства имен uri.

String expr="//prefix:QDTM_IN300401QD/controlActEvent/...."

, которое вы настроили с помощью сопоставления пространства имен,взгляните на https://www.ibm.com/developerworks/library/x-javaxpathapi/index.html и https://xml.apache.org/xalan-j/xpath_apis.html#namespacecontext

Если xml содержит только одно пространство имен, вы также можете попробовать использовать в своем выражении // *: elementname, чтобы просто игнорировать в каком пространстве имен имя элементасуществует.

Взгляните на http://www.w3schools.com/XML/xml_namespaces.asp, чтобы понять, как используются пространства имен и какую проблему они решают

0 голосов
/ 12 января 2012

Цель getNamespaceURI внутри NamespaceContext - связать каждое пространство имен в исходном документе с уникальным префиксом, чтобы механизм XPath знал, к какому пространству имен относится элемент, всякий раз, когда он встречает эту строку префикса в XPath выражение. Префикс здесь не должен совпадать с префиксом (если есть) для того же URI в исходном XML; ему просто нужно отобразить префикс в правильное пространство имен.

Итак, если бы вы написали следующее выражение:

//p:QDTM_IN300301QD/p:controlActEvent/p:subject/p:registrationEvent/p:subject
    /p:testCodeIdentifier/p:playingTestCodeDetails/p:code
        /p:translation[@codeSystemName='DOSCATALOGNAMEHTMLENABLED']
            /p:originalText/text()"

... тогда вы бы написали соответствующий getNamespaceURI так:

public String getNamespaceURI(String prefix) {
    if ("p".equals(prefix)) {
        return "urn:hl7-org:v3";
    } 
    return null;
}

Так движок знает, что нужно искать элемент в пространстве имен urn:hl7-org:v3 всякий раз, когда он сталкивается с префиксом p, что и составляет весь смысл. В противном случае, как движок узнает, что вам не нужен элемент с именем QDTM_IN300301QD в no пространстве имен? Или элемент с таким именем в каком-то другом пространстве имен?

Обратите внимание, что имя префикса произвольно; это может быть все, что вы хотите, пока это уникально. То есть, если в вашем документе есть другие пространства имен, вам нужно изменить getNamespaceURI, чтобы знать эти пространства имен и назначить уникальный префикс для каждого из них.

Вот полный (минимальный) пример:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true); 
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("Draft.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
NamespaceContext ctx = new NamespaceContext() {
    public String getNamespaceURI(String prefix) {
        if ("p".equals(prefix)) {
            return "urn:hl7-org:v3";
        } 
        return null;
    }
    public String getPrefix(String uri) {
        throw new UnsupportedOperationException();
    }
    public Iterator getPrefixes(String uri) {
        throw new UnsupportedOperationException();
    }
};
xpath.setNamespaceContext(ctx);
XPathExpression expr = xpath.compile("//p:QDTM_IN300301QD/p:controlActEvent" +
        "/p:subject/p:registrationEvent" + 
        "/p:subject/p:testCodeIdentifier/p:playingTestCodeDetails/p:code" +
        "/p:translation[@codeSystemName='DOSCATALOGNAMEHTMLENABLED']" +
        "/p:originalText/text()");      
System.out.println("[" + expr.evaluate(doc, XPathConstants.STRING));
...