如何使用XPath解析此XML?

时间:2014-08-05 13:56:03

标签: qt xml-parsing qt4 xquery

我想使用XPath解析以下XML。我使用这个查询:

query.setQuery("doc($xmlByteArry)//TEST/TEST_OUTPUT/FILE[@TEST_TYPE_ID_REF=1]");

我想获取PATH,TEST_PATH和ALIAS中的值,所以我编写了一个循环遍历QXmlResultItems的代码。但它似乎没有给我任何结果:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE TEST_XML>
<TEST TEST_VERSION="14">
 <TEST_TYPES>
  <TEST_TYPE ID="0"/>
  <TEST_TYPE ID="1"/>
 </TEST_TYPES>
 <TEST_QUERY_LIST PROP="0">
  <TEST_QUERY_FILE>"C:/Files/File.txt"</TEST_QUERY_FILE>
 </TEST_QUERY_LIST>
 <TEST_OUTPUT>
  <FILE PATH="C:/Files/File2.txt" TEST_TYPE_ID_REF="1">
   <USED_BY TEST_PATH="C:/Files/File2.txt" ALIAS="thisData"/>
   <USED_BY TEST_PATH="C:/Files/File3.txt" ALIAS="thatData"/>
  </FILE>
  <FILE PATH="C:/Files/File5.txt" TEST_TYPE_ID_REF="1">
   <USED_BY TEST_PATH="C:/Files/File4.txt" ALIAS="anotherData"/>
  </FILE>
  <FILE PATH="C:/Files/File2.txt" TEST_TYPE_ID_REF="0">
   <USED_BY TEST_PATH="C:/Files/File2.txt" ALIAS="thisData"/>
  </FILE>
 </TEST_OUTPUT>
</TEST>

用于解析上述XML的C ++代码:

   QByteArray xmlByteArry;
   QBuffer device(&xmlByteArry);
   device.setData(expected_xml.toUtf8());
   device.open(QIODevice::ReadOnly);

   QXmlQuery query;
   query.bindVariable("xmlByteArry", &device);
   query.setQuery("doc($xmlByteArry)//TEST/TEST_OUTPUT/FILE[@TEST_TYPE_ID_REF=1]");

   QString values;
   if(query.isValid())
   {
      QXmlResultItems result;
      query.evaluateTo(&result);
      QXmlItem XmlItem(result.next());
      while (!XmlItem.isNull()) 
      {
         //Code to parse the Internal ones
         if(XmlItem.isAtomicValue())
         {
            //I hope some values will be atomic like ALIAS and TEST_PATH
            values.append(XmlItem.toAtomicValue().toString());
         }
         else if (XmlItem.isNode()) 
         {
            //I hope to get the FILE Node and USED_BY node but I dont see anything in the following stringValue.
            QXmlNodeModelIndex Index = XmlItem.toNodeModelIndex();
            values.append(Index.stringValue());
         }
         XmlItem = result.next();
      }
      qDebug() << values;
   }

1 个答案:

答案 0 :(得分:1)

此查询应返回值:

... setQuery("for $x in doc($xmlByteArry)//TEST/TEST_OUTPUT/FILE"
    " return if($x/@TEST_TYPE_ID_REF = 1) "
    " then ($x/USED_BY/@TEST_PATH, $x/USED_BY/@ALIAS, $x/@PATH ) "
    " else ()");

<强> 更新:

我使用以下代码测试您的示例:

QString test7::XmlTree()
{
    return QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
        "<!DOCTYPE TEST_XML>"
        "<TEST TEST_VERSION=\"14\">"
        "<TEST_TYPES>"
        "<TEST_TYPE ID=\"0\"/>"
        "<TEST_TYPE ID=\"1\"/>"
        "</TEST_TYPES>"
        "<TEST_QUERY_LIST PROP=\"0\">"
        "<TEST_QUERY_FILE>\"C:/Files/File.txt\"</TEST_QUERY_FILE>"
        "</TEST_QUERY_LIST>"
        "<TEST_OUTPUT>"
        "<FILE PATH=\"C:/Files/File2.txt\" TEST_TYPE_ID_REF=\"1\">"
        "<USED_BY TEST_PATH=\"C:/Files/File2.txt\" ALIAS=\"thisData\"/>"
        "<USED_BY TEST_PATH=\"C:/Files/File3.txt\" ALIAS=\"thatData\"/>"
        "</FILE>"
        "<FILE PATH=\"C:/Files/File5.txt\" TEST_TYPE_ID_REF=\"1\">"
        "<USED_BY TEST_PATH=\"C:/Files/File4.txt\" ALIAS=\"anotherData\"/>"
        "</FILE>"
        "<FILE PATH=\"C:/Files/File2.txt\" TEST_TYPE_ID_REF=\"0\">"
        "<USED_BY TEST_PATH=\"C:/Files/File2.txt\" ALIAS=\"thisData\"/>"
        "</FILE>"
        "</TEST_OUTPUT>"
        "</TEST>");
}

void test7::test()
{
    QByteArray xmlByteArry;
    QBuffer device(&xmlByteArry);
    device.setData(XmlTree().toUtf8());
    device.open(QIODevice::ReadOnly);

    QXmlQuery query;
    query.bindVariable("xmlByteArry", &device);
    query.setQuery("for $x in doc($xmlByteArry)//TEST/TEST_OUTPUT/FILE"
        " return if($x/@TEST_TYPE_ID_REF = 1) "
        " then ($x/USED_BY/@TEST_PATH, $x/USED_BY/@ALIAS, $x/@PATH ) "
        " else ()");

    QString values;
    if(query.isValid())
    {
        QXmlResultItems result;
        query.evaluateTo(&result);
        QXmlItem XmlItem(result.next());
        while (!XmlItem.isNull()) 
        {
            //Code to parse the Internal ones
            if(XmlItem.isAtomicValue())
            {
                //I hope some values will be atomic like ALIAS and TEST_PATH
                values.append(XmlItem.toAtomicValue().toString());
            }
            else if (XmlItem.isNode()) 
            {
                //I hope to get the FILE Node and USED_BY node but I dont see anything in the following stringValue.
                QXmlNodeModelIndex Index = XmlItem.toNodeModelIndex();
                values.append(Index.stringValue());
            }
            XmlItem = result.next();
        }
        qDebug() << values;
    }
}

qDebug打印没有withespace的值列表:

"C:/Files/File2.txtC:/Files/File3.txtthisDatathatDataC:/Files/File2.txtC:/Files/File4.txtanotherDataC:/Files/File5.txt"