pugi xml创建xml
即使在旅途中,您也需要保持联系。 台式时,您可以使用台式VoIP电话进行呼叫; 旅行时,您使用智能手机。 但是,每台设备都要求其电话列表采用特定格式,每台设备都具有自己格式明确的联系人列表或电话簿。 如果需要,您可以两次输入所有联系人(每个联系人列表一次),然后,每次更改时,都在两个列表中进行更改。 当然,您可能更希望两部手机都从同一个后端源获取数据,在那里您只能在一个地方编辑姓名和电话号码。 这不成问题:您已连接Internet或Intranet,并且可以使用技术。 在本文中,了解来自单个MySQL数据库的数据如何为两个截然不同的设备提供联系信息:以snom 300系列设备代表的VoIP电话和以诺基亚E71设备形式的智能电话(请参阅参考资料) 。链接)。
台式设备:Snom 300系列
snom 300系列提供优质,坚固的VoIP电话,具有与办公环境相关的各种功能,例如保持,转接和会议。 虽然这款手机确实有从LDAP服务器提供的数据的原生支持,它也有一个迷你浏览器(见相关信息 ),可以读取HTML。 它甚至可以以可以触发电话的格式在电话屏幕上显示文本。
清单1提供了snom微型浏览器所需的XML格式的示例,特别是在电话簿上下文中。
清单1. snom XML微型浏览器的示例
<?xml version="1.0" encoding="UTF-8"?>
<SnomIPPhoneDirectory>
<Title>PhoneList - Snom</Title>
<DirectoryEntry>
<Name>Friend, First</Name>
<Telephone>555-456-7890</Telephone>
</DirectoryEntry>
<DirectoryEntry>
<Name>Person, Second</Name>
<Telephone>555-654-0987</Telephone>
</DirectoryEntry>
<SoftKeyItem>
<Name>F1</Name>
<Label>Dial</Label>
<SoftKey>F_ENTER</SoftKey>
</SoftKeyItem>
</SnomIPPhoneDirectory>
在此代码中,根元素SnomIPPhoneDirectory
具有三个不同的子代: Title
, DirectoryEntry
和SoftKeyItem
。 标题出现在电话显示屏的顶部,并在滚动过程中保持不变。 目录条目如下(每行一个)并且可以滚动。 软键项目与显示屏正下方的四个按钮相关。 这些按钮可执行诸如启动对当前突出显示的目录条目的调用之类的功能。 本示例中的数据由两个电话号码条目组成:显示名称和用于拨号的号码。 它仅激活一个按钮:按下F1按钮,电话开始拨号。
旅行设备:诺基亚E71智能手机
诺基亚E71设备是现代智能手机的一个很好的例子。 它可以与无线LAN或小区服务连接,具有会话发起协议(SIP)客户端,可以使用其自己的本机浏览器浏览Internet,并可以随时随地管理语音通信。
E71的设备能够无线应用协议(WAP)2.0版(WAP2-见相关主题 ) -而不是对与Wi-Fi保护访问II(WPA2)功能相混淆。 这意味着它可以读取XML格式的文件,这些文件可以通过各种功能在电话内部进行通信,例如打开一个窗口以发起呼叫。
清单2提供了一个智能电话需要WAP2 / XML格式的示例。 此示例使用与清单1相同的两个虚构条目。
清单2. WAP2 XML的示例
<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml" >
<wml>
<card id="main" title="PhoneList - Nokia">
Tel (WTAI): <a href="wtai://wp/mc;%2B555-456-7890">Friend, First</a><br />
Tel (WTAI): <a href="wtai://wp/mc;%2B555-654-0987">Person, Second</a>
</card>
</wml>
WAP2要求您以纸牌形式显示数据。 根元素<wml>
有一个子<card>
(或页面),两行之间用一个分隔符隔开。 页面标题列在根元素的属性中。 的电话号码在锚,或指示<a>
,元件,与<href>
属性使用无线电话应用接口(WTAI-见相关主题 )。 当您在电话浏览器中打开页面并单击电话链接时,会弹出一个窗口,询问您是否要拨打该号码,这时电话会找到进行呼叫的路由(无论是通过无线局域网还是使用其他方式)电话订阅。
由于智能电话没有处理LDAP的本机能力,而台式电话不处理WAP2,因此似乎没有什么共同点。 但是,脚本提供了使用XML适应性的解决方案。 您可能会找到一种通过智能手机将联系人与LDAP服务器同步的方法,但它可能不像直接动态访问信息那样干净。 幸运的是,尽管在两种模式下XML的格式可能会发生变化,但是数据基本上保持不变。
该方法
通过这两种设备对Internet的普遍访问,一种通用电话簿的一种解决方案是将所有数据保存在数据库中,然后使用脚本引擎生成XML文件,以将其传送到最方便的设备上的浏览器。 只要您知道哪个设备正在使用脚本,就可以传递正确的输出。 另外,脚本可以根据需要控制访问和筛选信息以进行传递。
数据库
数据可以多种格式存储并根据需要提取。 替代品包括PostgreSQL,XML,纯文本,IBM®DB2®以及许多其他产品。 清单3显示了MySQL的示例架构。
清单3.示例数据库模式
CREATE TABLE IF NOT EXISTS 'mycontacts' (
'id' int(11) NOT NULL auto_increment,
'firstName' varchar(30) default NULL,
'lastName' varchar(30) default NULL,
'number' varchar(20) default NULL,
PRIMARY KEY ('id')
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
该表仅包含四个字段(为方便起见,ID,名字和姓氏以及电话号码)和一个索引。 该模式提供了所需信息的基本知识。 可以根据需要添加其他字段和索引。 您可以编辑用的LibreOffice Base或phpMyEdit数据内容(见相关信息 )您选择的编辑器。
PHP生成器
清单4显示了一个基本脚本,该脚本从后端获取数据并以纯文本格式显示输出。 此时,您只是在测试脚本以确保其返回有意义的数据。
清单4.基本数据库生成器
<?php
$dev = "";
$db_host = "your.database.server";
$db_user = "your_user";
$db_pass = "your_password";
$db_name = "your_database";
$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name);
if (mysqli_connect_errno()) show_err($dev,"Could not connect to database");
$query = "SELECT * FROM mycontacts order by lastName asc";
$result = $mysqli->query($query);
$num = $result->num_rows;
$i = 0;
while ($row = $result->fetch_array()) {
$myarr[$i]['first']=$row["firstName"];
$myarr[$i]['last']=$row["lastName"];
$myarr[$i]['phone']=$row["number"];
$i++;
}
$mysqli->close();
switch ($dev) {
case 'snom':
echo mysnom($myarr);
break;
case 'noki':
echo mynoki($myarr);
break;
default:
echo mytest($myarr);
break;
}
function mytest($myarr) {
$cont = "Header\n";
foreach ($myarr as $a) {
$cont .= " ".$a['first']." ".$a['last']." ".$a['phone']."\n";
}
$cont .= "Footer\n";
return $cont;
}
function show_err($dev,$msg) {
die($msg);
}
?>
此代码首先定义用于访问数据库的变量,打开连接,然后返回结果集或消息(如果它无法连接到数据库)。 然后, while
循环遍历数据集,将信息存储在方便的数组中,以供以后显示。 由于设备变量$dev
初始化为长度为零的字符串,因此在执行switch
,它将变为默认值并调用mytest()
函数。 此函数显示一个简单的标题,写出数组的内容,然后打印页脚(全部以纯文本格式)。
该脚本仅处理一个可能的错误:连接数据库失败。 计划处理其他情况,例如成功连接到数据库但找到一个空表。 您可以使用对show_err()
函数的类似调用来捕获和处理这些情况。
大部分内容都已准备就绪,可以通用化此脚本以处理其他类型的设备。 switch
具有两部手机的保护套,但它们的功能尚不存在。 现在的挑战是使输出与其他目标设备相关,并按要求添加XML格式的详细信息。
桌面微型浏览器
参考清单1中的示例,您可以看到清单5中的功能添加了处理台式VoIP电话所需的部分。
清单5.处理桌面微型浏览器的函数
function mysnom($myarr) {
$cont = "<?xml version=\"1.0\"?>
<SnomIPPhoneDirectory>
<Title>MySQL Directory</Title>";
foreach ($myarr as $a) {
$cont .= "
<DirectoryEntry>
<Name>".$a['first']." ".$a['last']."</Name>
<Telephone>".$a['phone']."</Telephone>
</DirectoryEntry>\n";
}
$cont .= "</SnomIPPhoneDirectory>\n";
return $cont;
}
function show_err($dev,$msg) {
switch ($dev) {
case 'snom':
echo "<?xml version=\"1.0\"?>
<SnomIPPhoneText>
<Text>
$msg
</Text>
</SnomIPPhoneText>
";
break;
default:
echo $msg;
break;
}
die();
}
将清单5与清单4进行比较,这些新函数不是回显纯文本,而是回显包装在微型浏览器期望的元素中的数据。 mysnom()
函数是脚本的补充,而show_err()
函数是替代的。 微型浏览器无法显示纯文本:它什么也不做。 因此,正常输出和异常输出都需要XML输出。 因为您使用的是电话,所以错误消息必须出现在这里。 在无法连接数据库的情况下,脚本会将错误报告给手机。 如果成功,则在while
循环开始之前,脚本会声明根元素。 随着循环的进行,每条记录都包装在其自己的目录条目标签中。 循环完成后,按钮的设置开始。 仅用四个按钮,是否也需要在数据库中进行编码就值得怀疑。 最后,代码关闭根元素。
如果在代码开头正确设置了变量$dev
则上述函数将正常运行,如下所示:
$dev = "snom";
智能手机WAP2
对于诺基亚电话,您将添加输出详细信息,以WTAI引用的WAP2格式为智能电话提供XML。 清单6显示了代码。
清单6.处理智能电话WAP2的函数
function mynoki($myarr) {
$cont = "<?xml version=\"1.0\"?>
<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\"
\"http://www.wapforum.org/DTD/wml_1.1.xml\" >
<wml>\n
<card id=\"main\" title=\"PhoneList - Nokia\">\n";
foreach ($myarr as $a) {
$cont .= "\nTel (WTAI): <a href=\"wtai://wp/mc;%2B".$a['phone']."\">
".$a['last']." ".$a['first']."</a><br />";
}
$cont .= "</card></wml>\n";
return $cont;
}
同样,此代码提供了诺基亚手机所需的XML。 在与数据库建立连接时发生错误的情况下,文本输出不会包装在任何类型的标记中,因为简单的输出会在没有标记的情况下正确显示在电话上。 显示电话簿条目时,在循环开始之前,脚本会发送XML和DOCTYPE信息,然后打开根<wml>
元素和<card>
元素。 然后,循环开始,显示WTAI信息中包含的每一行。 最后,代码关闭卡和根<wml>
元素。
如果在代码开头正确设置了变量$dev
则上述函数将正常运行,如下所示:
$dev = "noki";
请注意,有关在诺基亚E71手机上使用联系人方法的建议并不打算完全替代本机联系人应用程序,它显然是电话系统的一部分,因此具有某些优势,因此与其他应用程序有着紧密的联系。 但是,可以使用相同的过程从同一MySQL数据库生成本机联系人列表,但以vCard(VCF)文件格式生成中间输出(请参阅参考资料 ),以导入到电话中。
检测设备
难题的最后一部分是让脚本在运行时知道需要哪个设备输出。 您可以通过多种方法来执行此操作,其中一种方法是在HTTP请求查询字符串中发送GET
信息。 想象一下,您发送以下请求,该请求明确指出了设备和用户:
http://www.myserver.tld/phonebook/myscript.php?device=snom&user=jim
然后, 清单7中的完整脚本解析了查询字符串,并在运行时将信息插入脚本中。
清单7.检测设备
<?php
if ($_GET['user'] != 'jim') show_err($dev,'Unauthorised access');
$dev = $_GET['device'];
$db_host = "your.database.server";
$db_user = "your_user";
$db_pass = "your_password";
$db_name = "your_database";
$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name);
if (mysqli_connect_errno()) show_err($dev,"Could not connect to database");
$query = "SELECT * FROM mycontacts order by lastName asc";
$result = $mysqli->query($query);
$num = $result->num_rows;
$i = 0;
while ($row = $result->fetch_array()) {
$myarr[$i]['first']=$row["firstName"];
$myarr[$i]['last']=$row["lastName"];
$myarr[$i]['phone']=$row["number"];
$i++;
}
$mysqli->close();
switch ($dev) {
case 'snom':
echo mysnom($myarr);
break;
case 'noki':
echo mynoki($myarr);
break;
default:
echo mytest($myarr);
break;
}
function mytest($myarr) {
$cont = "Header\n";
foreach ($myarr as $a) {
$cont .= " ".$a['first']." ".$a['last']." ".$a['phone']."\n";
}
$cont .= "Footer\n";
return $cont;
}
function mynoki($myarr) {
$cont = "<?xml version=\"1.0\"?>
<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\"
\"http://www.wapforum.org/DTD/wml_1.1.xml\" >
<wml>\n
<card id=\"main\" title=\"PhoneList - Nokia\">\n";
foreach ($myarr as $a) {
$cont .= "\nTel (WTAI): <a href=\"wtai://wp/mc;%2B".$a['phone']."\">
".$a['last']." ".$a['first']."</a><br />";
}
$cont .= "</card></wml>\n";
return $cont;
}
function mysnom($myarr) {
$cont = "<?xml version=\"1.0\"?>
<SnomIPPhoneDirectory>
<Title>MySQL Directory</Title>";
foreach ($myarr as $a) {
$cont .= "
<DirectoryEntry>
<Name>".$a['first']." ".$a['last']."</Name>
<Telephone>".$a['phone']."</Telephone>
</DirectoryEntry>\n";
}
$cont .= "</SnomIPPhoneDirectory>\n";
return $cont;
}
function show_err($dev,$msg) {
switch ($dev) {
case 'snom':
echo "<?xml version=\"1.0\"?>
<SnomIPPhoneText>
<Text>
$msg
</Text>
</SnomIPPhoneText>
";
break;
default:
echo $msg;
break;
}
die();
}
?>
这段代码基本上是清单4的重复,增加了清单5和清单6的功能,首先进行了细微的检查以查看用户是谁,并在错误的用户尝试访问信息的情况下在受控条件下停止。 然后,它从查询字符串中获取设备,并根据说明完成输出。
每部电话向数据库显示其自己的请求和查询字符串时,可以以设备可以显示的格式快速轻松地接收输出。
结论
您可以通过修改XML输出来使用其他平台上通用来源的联系人列表。 诺基亚的功能应可在任何符合WAP 2.0的电话上使用。 使snom功能适应其他电话可能会更加困难,但是如果尊重XML,那么您所需要的只是正确的架构。 您可以根据需要使用最方便的脚本语言轻松维护和扩展脚本。
翻译自: https://www.ibm.com/developerworks/xml/library/x-phonebook/index.html
pugi xml创建xml