SimpleRDFElement类使处理 RDF XML变得更容易

分享于 

12分钟阅读

Web开发

  繁體 雙語

介绍

资源描述框架是一种以简单序列化为XML的方式表示知识(。subject-predicate-object格式的语句)的方法的方法。 RDF中不同的"术语"由用户在RDF架构文档中可以用的不同词汇表定义,系统专门设计用于它的他定义: 你可以在 RDF XML文档中指定不同的词汇表作为命名空间,并使用它们定义的术语。 因此,典型的RDF文档包含大量命名空间中的元素。 由于RDF信息是以XML表示的,所以每个单元标记都通过命名空间前缀和每个父元素来限定。

当尝试使用他们的SimpleXML MODULE 解析 RDF XML时,这就出现了一个问题。 它提供了一个易于使用的SimpleXMLElement 类,只要你不处理名称空间。 当命名空间处理非常简单时,可以使用足够的 例如当元素的子元素都属于同一命名空间时。 但是没有简单的方法可以获取特定元素的命名空间前缀或者部分,也很难处理来自多个命名空间的子元素的元素。 这使得将 RDF XML转换为"三联"( 主语。谓语。对象) 表示形式的一段非常简单的代码,即由XML-mind-numbingly复杂对象表示的对象。

因此,我给出了 SimpleRDFElement 类: 扩展了内置 PHP SimpleXMLElement 类的类,使用一些额外的方法设计,以便在使用 RDF XML时更易于使用。

( 注意:本文的它的余部分是假设你熟悉 RDF。XML和PHP的基础知识,并知道"三"。"命名空间"和"对象方法"的含义。

背景

我一直致力于使用这些 XML/XML文本,并将它们转换为代表XML节点的对象,然后确定这些XML元素的表示形式以及它们的子树。 我想在PHP中使用内置的SimpleXML MODULE 功能,但是当我尝试时,我遇到了许多问题。 这是一些我在尝试使用 SimpleXMLElement 类表示 rdf/xml时遇到的一些问题的简短列表:

  • 因为 root 元素的所有子元素都限定为命名空间前缀,因此不能使用 -> 运算符将它们作为对象属性访问。
  • 由于创建子节点 array的方式,因此不能使用 print_r() 之类的方法将限定元素视为 array 元素。
  • 因为 children() 方法在没有参数时被调用,只返回非限定的(。例如,没有命名空间前缀) 元素,因这里无法返回任何内容。
  • 因这里,对象似乎是完全空的;如果你尝试将它作为布尔值( 比如 ),则甚至可以计算为"false"。 在赋值后添加" or die()"子句)
  • 调用带有名称空间的children() 方法时,它将只检索具有命名空间前缀的子元素
  • 因这里,如果期望元素的子元素来自多个命名空间,则必须对每个命名空间进行迭代。

( 如果你有点奇怪,我有一篇详细的博客文章,关于我在这里遇到的失败尝试和问题: ( http://talkingowlproject.blogspot.com/2011/06/simplexml-and-namespace-quirks.html )

谷歌在搜索这个问题的解决方案之后,我发现什么都不适合我的需要。 我可以下载大量需要安装PHP或者更多PHP类文件( 但是我想做的就是将RDF字符串解析为三元组。 我不需要所有这些) 或者我可以按照一些"hack"的建议来实现。 比如说,为了完全消除命名空间,一个人建议用"_"替换RDF字符串中的":"字符。 因为在XML文档中的命名空间前缀是任意的,所以这不适用于在文档的中定义的较长的uri。 不同的人可以使用不同的前缀来表示同一个名称空间 URI,并且不会产生差异。

所以我决定创建我自己的解决方案作为"轻量"替代方案。 它实际上是一个带有一个主类(。SimpleRDFElement 类) 和一个 helper 类(。SimpleRDFTriple 类)的文件。 实际上,它只需要在PHP中的SimpleXMLElement 类中添加一些 helper 方法。 但是这些方法在处理 RDF XML时,在世界上的所有差异。

因为这个解决方案简单简单,所以它没有做很多。 那是故意的:它不应该做很多事情。 这是简单问题的简单解决方法。 它将允许你将RDF文档解析为对象,并允许你访问命名空间信息。 它还提供了一种方法,该方法将从由对象及它的直接子级表示的顶级元素提取三元。 ( 这里方法不是递归的,因此你必须自己执行任何递归。)

我不能保证它对每个有效的rdf/xml文档都是绝对的。 然而,我打开了( 一些)的添加和改进,并修复了你找到的任何东西。 请与我联系,你的意见,建议和投诉。

使用代码

这里代码是一个包含两个PHP类定义的单个文件。

第一个类只是一个 helper 类 SimpleRDFTriple,它字面上是一个没有方法和三个属性的对象: tripleSubjecttriplePredicatetripleObject。 这个类的惟一原因是 SimpleRDFElement 类可以有一个方法 getTriples(),它返回该类型的对象的array。

第二个类 SimpleRDFElement 扩展了构建到PHP中的类 SimpleXMLElement,作为SimpleXML库的一部分。

因为类扩展了 SimpleXMLElement,所以可以通过使用内置函数 simplexml_load_string() 中包含 rdf/xml文本的字符串变量创建新的SimpleRDFElement:

$xmlobj = simplexml_load_string($xmltext,'SimpleRDFElement');

第一个参数是包含要解析的rdf/xml文本的变量,第二个参数是一个字符串: 我们扩展类的NAME,SimpleRDFElement。 这将返回 SimpleRDFElement 类型的对象,这意味着可以像 SimpleXMLElement 对象一样操作它,但是你也可以使用扩展类提供的新元素。

SimpleRDFClass 提供的新方法包括:

$xmlobj->getPrefix()

返回对象的root 元素的命名空间前缀,基于由XML文本定义的命名空间定义。

$xmlobj->getNamespace()

返回对象 root 元素的命名空间的完整 URI,基于由XML文本定义的命名空间定义。

$xmlobj->getFullName()

返回 root 元素的完全限定的NAME,使用prefix-colon-tagname格式。比如。rdfs:Class

$xmlobj->getFullURI()

使用名称空间的扩展URI返回 root 元素的完整 URI,后面跟有元素标记 NAME。比如 http://www.w3.org/2000/01/rdf-schema#Class。

$xmlobj->getChildNodes()

返回当前顶级元素的所有子元素( 作为 SimpleRDFElement 对象)的一个 array。 内置的children() 方法不同,它返回所有子元素,而不考虑命名空间。

$xmlobj->getAttributes()

返回当前顶级元素的所有属性( 作为单个 SimpleRDFElement 对象)的一个 array。 内置的attributes() 方法不同,它返回所有属性,而不考虑命名空间。

$xmlobj->getTriples()

返回 SimpleRDFTriple 对象的array。 这是一个简单的helper 类,它定义具有三个属性的对象: tripleSubjecttriplePredicatetripleObject。 这个方法解析顶级元素并根据该元素。它的属性和它的直接子元素构造三元组。 它不是递归的。

大多数方法很简单,如果你熟悉 RDF。XML和名称空间,它们的用法很明显。

惟一的复杂方法是 getTriples(),它基于 $xmlobject 表示的root 元素返回 SimpleRDFTriple 对象的array。

应该记住 getTriples() 不是递归的,因此将假定 root 节点表示一个RDF元素,其中包含三元组的主题和直接子元素,以及关于这个主题的对象信息。 这意味着如果你最初从完整的RDF/xml文档创建了 $xmlobj,那么 root 元素就是 to。

例如以下代码提供一个非常简单的rdf/xml字符串,并将演示如何提取它的所有三元代码:

$xmltext = '<rdf:rdf 
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
 xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<rdf:Description rdf:id="#someperson">
<rdfs:label>Bob</rdfs:label>
<rdf:type rdf:resource="http://xmlns.com/foaf/0.1/Person"/>
</rdf:Description>
</rdf:rdf>';$xmlobj = simplexml_load_string($xmltext,'SimpleRDFElement');foreach ($xmlobj->getChildNodes() as $child)
{
 foreach ($child->getTriples() as $trip)
 {
 print_r( $trip );
 }
}

这将产生以下输出文本:

SimpleRDFTriple Object
(
 [tripleSubject] => #someperson
 [triplePredicate] => http://www.w3.org/2000/01/rdf-schema#label [tripleObject] => Bob
)
SimpleRDFTriple Object
(
 [tripleSubject] => #someperson
 [triplePredicate] => http://www.w3.org/1999/02/22-rdf-syntax-ns#type [tripleObject] => http://xmlns.com/foaf/0.1/Person)

Points of Interest

源文件中的代码故意保持很简单,所以你可以看到它是如何完成的,而不是简单地使用它,你可以看到它是如何完成的,并将。

如果你提出一个特别聪明的扩展或者附加方法,让我知道它,我将把它添加到链接到上面的源代码的源代码中。

历史记录

这里类别上的更新或者与其相关的任何内容都将出现在博客上: http://talkingowlproject.blogspot.com/


  MAKE  RDF  
相关文章