2

我现在要指出,我是使用 saxon 的新手,我已经尝试按照包中的文档和示例进行操作,但我只是没有运气解决这个问题。

基本上,我正在尝试使用 saxon v8 在 java 中进行一些 xml 处理。为了让某些东西正常工作,我采用了包中包含的一个示例文件并根据我的需要进行了修改。只要我不使用名称空间,它就可以工作,这是我的问题。如何解决命名空间问题?我真的不在乎使用它,但它存在于我的 xml 中,所以我要么必须使用它,要么忽略它。任何一种解决方案都很好。

无论如何,这是我的入门代码。它什么也不做,只是进行一个 xpath 查询尝试将它用于硬编码的 xml 文档。

public static void main(String[] args) {
    String query = args[0];

    File XMLStream=null;
    String xmlFileName="doc.xml";
    OutputStream destStream=System.out;
    XQueryExpression exp=null;
    Configuration C=new Configuration();
    C.setSchemaValidation(false);
    C.setValidation(false);

    StaticQueryContext SQC=new StaticQueryContext(C);
    DynamicQueryContext DQC=new DynamicQueryContext(C);      
    QueryProcessor processor = new QueryProcessor(SQC);
    Properties props=new Properties();
    try{   
        exp=processor.compileQuery(query);
        XMLStream=new File(xmlFileName);
        InputSource XMLSource=new InputSource(XMLStream.toURI().toString());
        SAXSource SAXs=new SAXSource(XMLSource); 
        DocumentInfo DI=SQC.buildDocument(SAXs);
        DQC.setContextNode(DI);

        SequenceIterator iter = exp.iterator(DQC);
        while(true){
            Item i = iter.next();
            if(i != null){
                System.out.println(i.getStringValue());
            }
            else break;
        }
    }
    catch (Exception e){
        System.err.println(e.getMessage());
    }
}   

一个示例 XML 文件在这里...

<?xml version="1.0"?>
<ns1:animal xmlns:ns1="http://my.catservice.org/">
    <cat>
        <catId>8889</catId>
        <fedStatus>true</fedStatus>
    </cat>
</ns1:animal>

如果我使用包含命名空间的查询运行它,我会收到错误消息。例如: /ns1:animal/cat/给出错误:“Prefix ns1 has not been declared”。

如果我从查询中删除 ns1: ,它什么也没给我。如果我修改 xml 以删除“动物”前面的“ns1:”,我可以/animal/cat/成功运行查询。

任何帮助将不胜感激。谢谢。

4

2 回答 2

2

错误消息正确指出您的 xpath 表达式未指示名称空间前缀“ns1”的含义(绑定到)。仅仅因为要操作的文档碰巧使用了“ns1”的绑定并不意味着它就是应该使用的:这是因为在 XML 中,重要的是命名空间 URI,而前缀只是对真实事物的方便快捷方式。

那么:你如何定义绑定?有2种通用方式;要么提供可以解析前缀的上下文,要么在 XPath 表达式中嵌入实际的 URI。

关于第一种方法,来自 Saxon 作者的这封电子邮件提到了 JAXP 方法 XPath.setNamespaceContext(),同样,Jaxen XPath 处理器常见问题解答中有一些示例代码可以提供帮助。这不是很方便,因为您必须实现 NamespaceContext,但是一旦您有了实现你会被设置的。

所以符号方法......让我们看看:Top Ten Tips to Using XPath and XPointer展示了这个例子:

匹配使用命名空间声明的元素,例如:

xmlns:book="http://my.example.org/namespaces/book"

您使用 XPath 名称,例如:

{ http://my.example.org/namespaces/book } 部分

希望撒克逊人(或贾克森人)能理解这一点。

最后,如果您在使用上述解决方案之一时遇到任何问题,我建议您尽可能升级到 Saxon9。

于 2009-05-11T19:05:29.857 回答
0

如果您想开箱即用,可以查看embedding-xquery-in-java。有一个 github 项目,它使用 Saxon 来评估一些示例 XQuery 表达式。

问候

于 2010-01-23T19:24:37.647 回答