20.3. コア XML データへの独自の XML タグの追加

gst_xml_write によって作成されたコア XML に独自の XML タグを追加することができます。アプリケーションはこの機能を使うことで、保存されたプラグインにさらに情報を追加することができます。たとえば、編集者は独自の XML タグを使って画面上の要素の位置を挿入することができます。

独自の XML タグについては、名前空間を使って保存とロードを行うことを強く推奨します。こうすることで、独自の XML タグがコア XML タグと干渉する問題を防ぐことができます。

エレメントを保存する手順にフックを挿入するには、次のようなコードを記述して、GstElement にシグナルをリンクします。


xmlNsPtr ns;

  ...
  ns = xmlNewNs (NULL, "http://gstreamer.net/gst-test/1.0/", "test");
    ...
  pipeline = gst_element_factory_make ("pipeline", "pipeline");
  g_signal_connect (G_OBJECT (pipeline), "object_saved", 
  		     G_CALLBACK (object_saved), g_strdup ("decoder pipeline"));
    ...
    

スレッドが保存されるときに、object_save メソッドが呼ばれます。ここでは、comment タグを挿入します。


static void
object_saved (GstObject *object, xmlNodePtr parent, gpointer data)
{
  xmlNodePtr child;

  child = xmlNewChild (parent, ns, "comment", NULL);
  xmlNewChild (child, ns, "text", (gchar *)data);
}
    

上の例に custom タグのコードを追加すると、XML ファイルに独自のタグが挿入されます。次に示すのは、独自のタグが追加された XML ファイルの一部です。


          ...
        <gst:element>
          <gst:name>pipeline</gst:name>
          <gst:type>pipeline</gst:type>
          <gst:version>0.1.0</gst:version>
	  ...
        </gst:children>
        <test:comment>
          <test:text>decoder pipeline</test:text>
        </test:comment>
      </gst:element>
          ...
    

独自の XML を取得するには、XML データのロードに使用する GstXML にシグナルをアタッチする必要があります。その後は、オブジェクトがロードされるたびに XML ツリーから独自の XML をパースできます。

これまでのコードは、次のように拡張できます。


  xml = gst_xml_new ();

  g_signal_connect (G_OBJECT (xml), "object_loaded", 
  		     G_CALLBACK (xml_loaded), xml);

  ret = gst_xml_parse_file (xml, "xmlTest.gst", NULL);
  g_assert (ret == TRUE);
    

これで、新しいオブジェクトがロードされるたびに、xml_loaded 関数が呼び出されます。次に示すのが、その xml_loaded 関数です。


static void
xml_loaded (GstXML *xml, GstObject *object, xmlNodePtr self, gpointer data)
{
  xmlNodePtr children = self->xmlChildrenNode;

  while (children) {
    if (!strcmp (children->name, "comment")) {
      xmlNodePtr nodes = children->xmlChildrenNode;

      while (nodes) {
        if (!strcmp (nodes->name, "text")) {
          gchar *name = g_strdup (xmlNodeGetContent (nodes));
          g_print ("object %s loaded with comment '%s'\n",
                   gst_object_get_name (object), name);
        }
        nodes = nodes->next;
      }
    }
    children = children->next;
  }
}
    

上のコードからわかるように、GstXML オブジェクト、新しくロードされた GstObject、および xmlNodePtr へのハンドルが渡されます。上の例では、オブジェクトをロードするのに使われた XML ツリー内部で、あらかじめ挿入しておいた特別なタグを探し、そのコメントをコンソールに表示しています。