2013-07-16 1 views
2

Я использую rapidXML и C++ в VS2012 на ПК. Я уже разбирал XML-файл, но теперь я хочу распечатать значения атрибутов отдельно. Обычно я могу это сделать, используя следующий код. Однако этот метод должен знать имя узла и имя атрибута. Это проблема, потому что у меня есть несколько узлов с тем же именем и несколькими атрибутами с тем же именем. Мой вопрос в том, как получить одно значение атрибута, когда ни имя узла, ни имя атрибута не уникальны?RapidXML Доступ к отдельному значению атрибута с использованием предыдущего значения атрибута?

код я использую, когда у меня есть уникальное имя узла и имя атрибута:

xml_node<> *node0 = doc.first_node("NodeName"); //define the individual node you want to access 
xml_attribute<> *attr = node0->first_attribute("price"); //define the individual attribute that you want to access 
cout << "Node NodeName has attribute " << attr->name() << " "; 
cout << "with value " << attr->value() << "\n"; 

Мой файл теста XML:

<catalog> 
    <book> 
     <author>Gambardella, Matthew</author> 
     <title>XML Developer's Guide</title> 
     <price>44.95</price> 
    </book> 
    <book> 
    <author>Ralls, Kim</author> 
    <title>Midnight Rain</title> 
    <price>5.95</price> 
    </book> 
</catalog> 

Для этого конкретного примера, как я могу получить значение атрибут цены на вторую книгу? Могу ли я ввести значение атрибута title «Midnight Rain» и каким-то образом использовать его для получения следующего значения?

+1

'цена' не является атрибутом, это узел. XML-атрибуты выглядят как '' – Roddy

ответ

1

Вы можете использовать функцию-член next_sibling(const char *) для перебора узлов-близнецов до тех пор, пока не найдете значение с правильным значением атрибута. Я не тестировал следующий код, но он должен дать представление о том, что вам нужно сделать:

typedef rapidxml::xml_node<>  node_type; 
typedef rapidxml::xml_attribute<> attribute_type; 

/// find a child of a specific type for which the given attribute has 
/// the given value... 
node_type *find_child( 
    node_type *parent, 
    const std::string &type, 
    const std::string &attribute, 
    const std::string &value) 
{ 
    node_type *node = parent->first_node(type.c_str()); 
    while (node) 
    { 
     attribute_type *attr = node->first_attribute(attribute.c_str()); 
     if (attr && value == attr->value()) return node; 
     node = node->next_sibling(type.c_str()); 
    } 
    return node; 
} 

Вы могли бы найти вторую книгу по телефону:

node_type *midnight = find_child(doc, "book", "title", "Midnight Rain"); 

Получение цены эта книга должна быть легкой.

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

+0

Ваш код не запущен, потому что node_type является «неоднозначным символом» ... Я также не совсем понимаю, что пытается выполнить node_type. Как вы думаете, вы могли бы прокомментировать свой код немного больше или, возможно, даже проверить его самостоятельно? Я прошу прощения, если эта проблема кажется очевидной, это моя первая работа с quickxml. –

+0

, видимо, в вашей среде у вас уже есть символ «node_type». Вы можете заменить node_type в коде выше с помощью xml_node <>. Обратите внимание, что это всего лишь иллюстрация. Ключевое сообщение: используйте 'next_sibling (const char *)', как в приведенном выше примере. – dhavenith

0

Когда вы говорите несколько узлов с тем же именем и несколькими атрибутами с тем же именем, вы имеете в виду; несколько узлов и несколько атрибутов? Если это так, я думаю, вы пытаетесь передать несколько сообщений xml. Однако вы должны сначала передать первое xml-сообщение, а затем второе сообщение. Вы не включили весь код, я бы сначала проверял, действительно ли метод doc.first_node создает xml_node.

Смежные вопросы