0

次のドキュメントが与えられた場合、抽出したいと思いtns:EchoResponseます。(元のドキュメントは読みやすくするために整形されています。)

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <tns:EchoResponse 
          xmlns:tns="http://www.apis-it.hr/fin/2012/types/f73" 
          xsi:schemaLocation="http://www.apis-it.hr/fin/2012/types/f73 FiskalizacijaSchema.xsd "
          >
            hello
         </tns:EchoResponse>
    </soap:Body>
</soap:Envelope>

ドキュメントを解析し、XPath コンテキストを作成し、名前空間soapとを登録tnsし、次の XPath 式を使用してクエリを実行しました。

//soap:Envelope[1]/soap:Body[1]/tns:EchoResponse[1]

残念ながら、名前空間を無視してローカル名のみを使用するルックアップのみが機能するようです。

//*[local-name(.) = 'Envelope']/*[local-name(.) = 'Body'][1]/*[local-name(.) = 'EchoResponse'][1]

それで…私は何を間違えましたか?私は何を誤って仮定しましたか? このドキュメントを扱うコードのスニペットを次に示します。

    xmlDocPtr xmldoc = xmlReadMemory(databuffer, datasize, ISFEndpointURL(), NULL, 0);
    if(!xmldoc)
    {
        err = -1;
        goto finalize;
    }

    xmlXPathContextPtr xpathCtx = xmlXPathNewContext(xmldoc);
    if(!xpathCtx)
    {
        err = -1;
        xmlFreeDoc(xmldoc);
        goto finalize;
    }

    xmlXPathRegisterNs(xpathCtx, BAD_CAST "soap", BAD_CAST "http://schemas.xmlsoap.org/soap/envelope");
    xmlXPathRegisterNs(xpathCtx, BAD_CAST "tns", BAD_CAST "http://www.apis-it.hr/fin/2012/types/f73");

    // //soap:Envelope[1]/soap:Body[1]/*[local-name(.) = 'EchoResponse']
    xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(BAD_CAST "./*[local-name(.) = 'Envelope']/*[local-name(.) = 'Body'][1]/*[local-name(.) = 'EchoResponse'][1]", xpathCtx);
    if(!xpathObj)
    {
        err = -1;
        xmlXPathFreeContext(xpathCtx);
        xmlFreeDoc(xmldoc);
        goto finalize;
    }
    if(xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)){
        err = -1;
        xmlXPathFreeObject(xpathObj);
        xmlXPathFreeContext(xpathCtx);
        xmlFreeDoc(xmldoc);
        printf("%s: No XPath result\n", __FUNCTION__);
        goto finalize;
    }


    if(strcmp((char *)xmlXPathCastNodeSetToString(xpathObj->nodesetval), echoText))
    {
        err = 1;
        xmlXPathFreeObject(xpathObj);
        xmlXPathFreeContext(xpathCtx);
        xmlFreeDoc(xmldoc);
        printf("%s: Incorrect echo result: %s\n", __FUNCTION__, xpathObj->stringval);
        goto finalize;
    }

    xmlXPathFreeObject(xpathObj);
    xmlXPathFreeContext(xpathCtx);
4

1 に答える 1

2

XML ドキュメントのsoapプレフィックスは名前空間 URI にバインドされます

http://schemas.xmlsoap.org/soap/envelope/

soap一方、コードはXPath コンテキストのプレフィックスを別の URI にバインドします

http://schemas.xmlsoap.org/soap/envelope

間違った名前空間を探しているため、XPath は何にも一致しません。

于 2013-01-29T14:50:44.340 に答える