java dom读写xml_用PHP读写XML DOM

java dom读写xml

用PHP读写可扩展标记语言(XML)似乎有些令人恐惧。 实际上,XML及其所有相关技术可能令人生畏。 但是,用PHP读写XML并不是一项艰巨的任务。 首先,您需要了解一些有关XML的知识-XML的含义和用途。 然后,您需要学习如何在PHP中读取和编写XML,您可以通过多种方式进行操作。

本文提供了有关XML的简短入门,然后说明了如何在PHP中读写XML。

什么是XML?

XML是一种数据存储格式。 它没有定义要存储什么数据或该数据的结构。 XML仅定义标签和这些标签的属性。 格式正确的XML标签如下所示:

<name>Jack Herrington</name>

<name>标记包含一些文本:Jack Herrington。

不包含文本的XML标签如下所示:

<powerUp />

用XML编写代码的方法可能不止一种。 例如,此标记产生与上一个相同的输出:

<powerUp></powerUp>

您还可以将属性添加到XML标记。 例如,此<name>标记包含firstlast属性:

<name first="Jack" last="Herrington" />

您也可以用XML编码特殊字符。 例如,“&”号的编码如下:

&

包含标签和格式化等提供良好形成的实例中,这意味着标记属性的XML文件是平衡的,且字符被正确编码。 清单1是格式良好的XML的示例。

清单1.一个XML书单示例
<books>
  <book>
  <author>Jack Herrington</author>
  <title>PHP Hacks</title>
  <publisher>O'Reilly</publisher>
  </book>
  <book>
  <author>Jack Herrington</author>
  <title>Podcasting Hacks</title>
  <publisher>O'Reilly</publisher>
  </book>
  </books>

清单1中的XML包含书籍列表。 父<books>标记包括一组<book>标记,每个标记都包含<author><title><publisher>标记。

当标记的结构及其内容由外部架构文件验证时,XML文档才有效。 可以以多种格式指定模式文件。 出于本文的目的,您需要的只是格式良好的XML。

如果您认为XML很像超文本标记语言(HTML),那是对的。 XML和HTML都是基于标记的语言,它们具有许多相似之处。 但是,必须注意,尽管XML文档可以是格式正确HTML,但并非所有HTML文档都是格式良好的XML。 break标签( br )是XML和HTML之间差异的一个很好的例子。 此换行符是格式正确HTML,但格式不正确的XML:

<p>This is a paragraph<br>
With a line break</p>

此换行符是格式正确的XML和HTML:

<p>This is a paragraph<br />
With a line break</p>

如果要编写格式正确的XMLHTML,请遵循万维网联盟(W3C)的可扩展超文本标记语言(XHTML)标准。 所有现代浏览器都呈现XHTML。 另外,可以使用XML工具读取XHTML并在文档中查找数据,这比通过HTML解析要容易得多。

使用DOM库读取XML

读取格式正确的XML文件的最简单方法是使用编译为某些PHP安装中的文档对象模型(DOM)库。 DOM库将整个XML文档读入内存并将其表示为节点树,如图1所示。

图1.书籍XML的XML DOM树
XML书籍的XML DOM树

树顶部的books节点具有两个子book标签。 每本书中都有authorpublishertitle节点。 authorpublishertitle节点每个都有包含文本的子文本节点。

清单2显示了读取书籍XML文件并使用DOM显示内容的代码。

清单2.使用DOM阅读XML
<?php
  $doc = new DOMDocument();
  $doc->load( 'books.xml' );
  
  $books = $doc->getElementsByTagName( "book" );
  foreach( $books as $book )
  {
  $authors = $book->getElementsByTagName( "author" );
  $author = $authors->item(0)->nodeValue;
  
  $publishers = $book->getElementsByTagName( "publisher" );
  $publisher = $publishers->item(0)->nodeValue;
  
  $titles = $book->getElementsByTagName( "title" );
  $title = $titles->item(0)->nodeValue;
  
  echo "$title - $author - $publisher\n";
  }
  ?>

该脚本首先创建一个new DOMdocument对象,然后使用load方法将书籍XML加载到该对象中。 之后,脚本使用getElementsByName方法获取具有给定名称的所有元素的列表。

book节点的循环内,脚本使用getElementsByName方法获取authorpublishertitle标签的nodeValuenodeValue是节点内的文本。 然后,脚本将显示这些值。

您可以在命令行上运行PHP脚本,如下所示:

% php e1.php
PHP Hacks - Jack Herrington - O'Reilly
Podcasting Hacks - Jack Herrington - O'Reilly
%

如您所见,每个书芯都会打印一行。 这是一个好的开始。 但是,如果您无权访问XML DOM库怎么办?

使用SAX解析器读取XML

读取XML的另一种方法是使用XML的简单API(SAX)解析器。 PHP的大多数安装都包括SAX解析器。 SAX解析器在回调模型上运行。 每次打开或关闭标签时,或者每当解析器看到一些文本时,它都会使用节点或文本信息对某些用户定义的函数进行回调。

SAX解析器的优点是它非常轻巧。 解析器不会在内存中保留任何内容很长时间,因此可以用于超大文件。 缺点是编写SAX解析器回调很麻烦。 清单3显示了读取书籍XML文件并使用SAX显示内容的代码。

清单3.使用SAX解析器阅读XML
<?php
  $g_books = array();
  $g_elem = null;
  
  function startElement( $parser, $name, $attrs ) 
  {
  global $g_books, $g_elem;
  if ( $name == 'BOOK' ) $g_books []= array();
  $g_elem = $name;
  }
  
  function endElement( $parser, $name ) 
  {
  global $g_elem;
  $g_elem = null;
  }
  
  function textData( $parser, $text )
  {
  global $g_books, $g_elem;
  if ( $g_elem == 'AUTHOR' ||
  $g_elem == 'PUBLISHER' ||
  $g_elem == 'TITLE' )
  {
  $g_books[ count( $g_books ) - 1 ][ $g_elem ] = $text;
  }
  }
  
  $parser = xml_parser_create();
  
  xml_set_element_handler( $parser, "startElement", "endElement" );
  xml_set_character_data_handler( $parser, "textData" );
  
  $f = fopen( 'books.xml', 'r' );
  
  while( $data = fread( $f, 4096 ) )
  {
  xml_parse( $parser, $data );
  }
  
  xml_parser_free( $parser );
  
  foreach( $g_books as $book )
  {
  echo $book['TITLE']." - ".$book['AUTHOR']." - ";
  echo $book['PUBLISHER']."\n";
  }
  ?>

该脚本首先设置g_books数组和g_elem变量,该数组将所有书籍及其信息保存在内存中,该变量存储脚本当前正在处理的标签的名称。 然后,脚本定义了回调函数。 在此示例中,回调函数为startElementendElementtextData 。 分别在打开和关闭标签时调用startElementendElement函数。 在标签开始和结束之间的文本上调用textData函数。

在此示例中, startElement标记正在寻找book标记以启动book数组中的新元素。 然后, textData函数查看当前元素以查看它是publishertitle还是author标记。 如果是这样,该函数会将当前文本放入当前书中。

为了进行解析,脚本使用xml_parser_create函数创建了解析器。 然后,它设置回调处理程序。 之后,脚本读取文件并将文件的大块发送给解析器。 读取文件后, xml_parser_free函数删除解析器。 脚本的末尾转储g_books数组的内容。

如您所见,这比DOM等效代码要难得多。 如果您没有DOM库或SAX库怎么办? 还有其他选择吗?

使用正则表达式解析XML

我肯定会提到某些方法而受到某些工程师的抨击,但是您可以使用正则表达式解析XML。 清单4显示了一个使用preg_函数读取books文件的示例。

清单4.阅读带有正则表达式的XML
<?php
  $xml = "";
  $f = fopen( 'books.xml', 'r' );
  while( $data = fread( $f, 4096 ) ) { $xml .= $data; }
  fclose( $f );
  
  preg_match_all( "/\<book\>(.*?)\<\/book\>/s", 
  $xml, $bookblocks );
  
  foreach( $bookblocks[1] as $block )
  {
  preg_match_all( "/\<author\>(.*?)\<\/author\>/", 
  $block, $author );
  preg_match_all( "/\<title\>(.*?)\<\/title\>/", 
  $block, $title );
  preg_match_all( "/\<publisher\>(.*?)\<\/publisher\>/", 
  $block, $publisher );
  echo( $title[1][0]." - ".$author[1][0]." - ".
  $publisher[1][0]."\n" );
  }
  ?>

注意该代码有多短。 首先将文件读取为一个大字符串。 然后,它使用一个regex函数读取每个书本。 最终,脚本使用foreach循环,在每个书芯周围循环,并挑选出作者,书名和出版商。

那么,缺点是什么呢? 使用正则表达式代码读取XML的问题在于,它不会首先检查以确保XML格式正确。 这意味着在开始阅读XML之前,您可能不知道自己的XML格式不正确。 另外,某些有效形式的XML可能与您的正则表达式不匹配,因此您稍后必须对其进行修改。

我从不建议使用正则表达式来读取XML,但有时这是最兼容的方式,因为正则表达式函数始终可用。 不要使用正则表达式来读取直接来自用户的XML。 您无法控制该XML的形式或结构。 始终使用DOM库或SAX解析器从用户读取XML。

用DOM编写XML

读取XML只是方程式的一部分。 怎么写呢? 编写XML的最好方法是使用DOM。 清单5显示了DOM如何构建书籍XML文件。

清单5.用DOM编写XML书籍
<?php
  $books = array();
  $books [] = array(
  'title' => 'PHP Hacks',
  'author' => 'Jack Herrington',
  'publisher' => "O'Reilly"
  );
  $books [] = array(
  'title' => 'Podcasting Hacks',
  'author' => 'Jack Herrington',
  'publisher' => "O'Reilly"
  );
  
  $doc = new DOMDocument();
  $doc->formatOutput = true;
  
  $r = $doc->createElement( "books" );
  $doc->appendChild( $r );
  
  foreach( $books as $book )
  {
  $b = $doc->createElement( "book" );
  
  $author = $doc->createElement( "author" );
  $author->appendChild(
  $doc->createTextNode( $book['author'] )
  );
  $b->appendChild( $author );
  
  $title = $doc->createElement( "title" );
  $title->appendChild(
  $doc->createTextNode( $book['title'] )
  );
  $b->appendChild( $title );
  
  $publisher = $doc->createElement( "publisher" );
  $publisher->appendChild(
  $doc->createTextNode( $book['publisher'] )
  );
  $b->appendChild( $publisher );
  
  $r->appendChild( $b );
  }
  
  echo $doc->saveXML();
  ?>

在脚本的顶部, books数组中装有一些示例书。 该数据可能来自用户或数据库。

加载示例书籍后,脚本将创建一个new DOMDocument并将根books节点添加到其中。 然后,脚本为每本书的作者,标题和出版者创建一个元素,并向每个节点添加一个文本节点。 每个工作book节点的最后一步是将其重新连接到根工作books节点。

脚本的末尾使用saveXML方法将XML转储到控制台。 (您还可以使用save方法从XML创建文件。)脚本的输出如清单6所示。

清单6. DOM构建脚本的输出
% php e4.php 
  <?xml version="1.0"?>
  <books>
  <book>
  <author>Jack Herrington</author>
  <title>PHP Hacks</title>
  <publisher>O'Reilly</publisher>
  </book>
  <book>
  <author>Jack Herrington</author>
  <title>Podcasting Hacks</title>
  <publisher>O'Reilly</publisher>
  </book>
  </books>
  %

使用DOM的真正价值在于它创建的XML总是格式正确的。 但是,如果您无权访问DOM来创建XML,该怎么办?

用PHP编写XML

如果DOM不可用,则可以使用PHP文本模板编写XML。 清单7显示了PHP如何构建书籍XML文件。

清单7.用PHP编写XML书籍
<?php
  $books = array();
  $books [] = array(
  'title' => 'PHP Hacks',
  'author' => 'Jack Herrington',
  'publisher' => "O'Reilly"
  );
  $books [] = array(
  'title' => 'Podcasting Hacks',
  'author' => 'Jack Herrington',
  'publisher' => "O'Reilly"
  );
  ?>
  <books>
  <?php
  
  foreach( $books as $book )
  {
  ?>
  <book>
  <title><?php echo( $book['title'] ); ?></title>
  <author><?php echo( $book['author'] ); ?>
  </author>
  <publisher><?php echo( $book['publisher'] ); ?>
  </publisher>
  </book>
  <?php
  }
  ?>
  </books>

该脚本的顶部类似于DOM脚本。 脚本的底部打开books标签,然后遍历每本书,创建book标签以及所有内部titleauthorpublisher标签。

这种方法的问题是对实体进行编码。 为了确保实体正确编码,必须在每个项目上调用htmlentities函数,如清单8所示。

清单8.使用htmlentities函数编码实体
<books>
  <?php
  
  foreach( $books as $book )
  {
  $title = htmlentities( $book['title'], ENT_QUOTES );
  $author = htmlentities( $book['author'], ENT_QUOTES );
  $publisher = htmlentities( $book['publisher'], ENT_QUOTES );
  ?>
  <book>
  <title><?php echo( $title ); ?></title>
  <author><?php echo( $author ); ?> </author>
  <publisher><?php echo( $publisher ); ?>
  </publisher>
  </book>
  <?php
  }
  ?>
  </books>

这就是为什么用基本PHP编写XML很烦人的原因。 您认为自己正在创建完美的XML,但是随后发现当您尝试通过XML运行数据时,某些元素的编码不正确。

结论

XML一直围绕着它大肆宣传和混乱。 但是,这并不像您想象的那么难,特别是在像PHP这样的出色语言中。 正确理解和实现XML后,您会发现可以使用许多强大的工具。 XPath和XSLT是两个值得一试的工具。


翻译自: https://www.ibm.com/developerworks/xml/library/os-xmldomphp/index.html

java dom读写xml

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值