我有以下功能:
function translate($params) {
$xmldata = '<?xml version="1.0" encoding="UTF-8" ?><root>' . html_entity_decode($params['data']) . '</root>';
$lang = ucfirst(strtolower($params['lang']));
if (simplexml_load_string($xmldata) === FALSE) {
return $params['data'];
} else {
$langxmlobj = new SimpleXMLElement($xmldata);
if ($langxmlobj -> $lang) {
return ($langxmlobj -> $lang);
} else {
return $params['data'];
}
}
}
适合使用以下字符串:
$params['data'] = '<English>Hello</English><French>Bonjour</French>';
$params['lang'] = 'English';
print translate($params);
输出:
Hello
但是......
当字符串中包含任何其他标记时:
$params['data'] = '<English><h1>Hello</h1></English><French><h1>Bonjour</h1></French>';
$params['lang'] = 'English';
它不输出任何东西;
我希望它输出:
<h1>Hello</h1> or any other tag within the <LanguageQuotes>
把我的头发拉出来;任何想法?
VERSION2:
当字符串如下时,它不起作用:
$data = '<French><li><span class="pull-right">25 GB</span>Espace disque</French><English><li><span class="pull-right">25 GB</span>Disk Space</English>
<French><li><span class="pull-right">YES</span>PHP 5, MySQL 5</French><English><li><span class="pull-right">YES</span>PHP 5, MySQL 5</English>
<French><li><span class="pull-right">100</span>Bases de données</French><English><li><span class="pull-right">100</span>Databases</English>
<French><li><span class="pull-right">∞</span>E-Mails</French><English><li><span class="pull-right">∞</span>E-mails</English>';
答案 0 :(得分:3)
你的问题有两个部分。
这里的主要问题是它不是有效的XML片段,而是HTML片段与某些特定标签的混合。幸运的是DOMDocument可以加载(和修复)HTML。默认情况下,这不会将数据加载为UTF-8,您需要添加指定编码的元标记。
$data = '<French><li><span class="pull-right">25 GB</span>Espace disque</French><English><li><span class="pull-right">25 GB</span>Disk Space</English>
<French><li><span class="pull-right">YES</span>PHP 5, MySQL 5</French><English><li><span class="pull-right">YES</span>PHP 5, MySQL 5</English>
<French><li><span class="pull-right">100</span>Bases de données</French><English><li><span class="pull-right">100</span>Databases</English>
<French><li><span class="pull-right">∞</span>E-Mails</French><English><li><span class="pull-right">∞</span>E-mails</English>';
$html_data =
'<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head>
<body>'.$data.'</body>';
libxml_use_internal_errors(TRUE);
$dom = new DOMDocument();
$dom->loadHtml($html_data);
$dom->formatOutput = TRUE;
echo $dom->saveXml();
输出:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<body>
<french>
<li><span class="pull-right">25 GB</span>Espace disque</li>
</french>
<english>
<li><span class="pull-right">25 GB</span>Disk Space</li>
</english>
<french>
<li><span class="pull-right">YES</span>PHP 5, MySQL 5</li>
</french>
<english>
<li><span class="pull-right">YES</span>PHP 5, MySQL 5</li>
</english>
...
</body>
</html>
正如您所看到的,它保留了语言名称元素,但将所有名称转换为小写。如果缺少html
和body
元素,它总会添加,但这不是问题。
现在你有了一个DOM,你可以使用XPath来获取节点。
一种可能性是获取body元素并将其导入SimpleXML:
$xpath = new DOMXpath($dom);
$root = simplexml_import_dom($xpath->evaluate('/html/body')->item(0));
var_dump($root);
输出:
object(SimpleXMLElement)#4 (2) {
["french"]=>
array(4) {
[0]=>
object(SimpleXMLElement)#3 (1) {
["li"]=>
object(SimpleXMLElement)#12 (1) {
["span"]=>
string(5) "25 GB"
}
}
...
}
["english"]=>
array(4) {
[0]=>
object(SimpleXMLElement)#5 (1) {
["li"]=>
object(SimpleXMLElement)#12 (1) {
["span"]=>
string(5) "25 GB"
}
}
...
或直接获取节点并将其保存为HTML片段:
$xpath = new DOMXpath($dom);
$string = '';
foreach ($xpath->evaluate('/html/body/*[name() = "english"]/*') as $node) {
$string .= $dom->saveHtml($node);
}
echo $string;
输出:
<li>
<span class="pull-right">25 GB</span>Disk Space</li><li>
<span class="pull-right">YES</span>PHP 5, MySQL 5</li><li>
<span class="pull-right">100</span>Databases</li><li>
<span class="pull-right">∞</span>E-mails</li>
答案 1 :(得分:0)
这种方法可能会对您有所帮助。我不是用XML封装数据,我认为这不是必需的。您只需要在两个自定义标签之间找到数据。
/**
* $matches[0] -> Returns string with the custom tag
* $matches[1] -> Returns string without the custom tag
*
* @param string $data
* @param string $tag
* @return string
*/
function find_between_custom_tag($data, $tag) {
$regex = '/<' . $tag . '>(.*?)<\/' . $tag . '>/';
preg_match($regex, $data, $matches);
return $matches[1];
}
$data = '<English><h1>Hello</h1></English><French><h1>Bonjour</h1></French>';
$tag = 'English';
echo '<pre>';
echo htmlspecialchars( find_between_custom_tag($data, $tag) );
echo '</pre>';
<强>输出:强>
<h1>Hello</h1>
答案 2 :(得分:0)
我不确定这是否适合您的目的,但您可以使用正则表达式检查您的代码。
function extractXML($data,$ce) {
$all = array(
"en" => "english",
"fr" => "french",
);
$lang = $all[$ce];
if (!$lang) { $lang='english'; }
$re = "/\<".$lang."?\>(.*?)\<\/".$lang."\>/i";
preg_match_all($re,$data,$matches);
foreach ($matches[1] as $name) {
$return .= $name;
}
return $return;
}
//Load your XML data
$test = '
<english>This is in english</english>
<english><div><span>This is also in english</span></div></english>
<french><div><span>This is some text</span></div></french>
<french><span>Regex Power!</span></french>
';
$str = '<?xml version="1.0" encoding="UTF-8" ?><root></root>';
echo $str.extractXMLLang($test,'en');
这将正确返回语言中的所有标记。只需使用extractXMLLang(String,Language-Abbreviation)
答案 3 :(得分:0)
如前所述:在版本2中,您的XML无效,因为您在XML-Tags中使用了非结束HTML。
如果要将HTML保留在XML中,则需要通过HTML实体替换HTML代码的特殊字符。为此,您可以使用函数htmlspecialchars()
。您也可以使用htmlentities()
作为替代方案。后者替换了更多的字符。
可以使用函数html_entity_decode()
来替换HTML实体。
示例:强>
$htmlSpecialFrench = htmlspecialchars('<li><span class="pull-right">25 GB</span>Espace disque');
然后,$htmlSpecialFrench
的值为:
<li><span class="pull-right">25 GB</span>Espace disque
对于此示例,必须对$htmlSpecialEnglish
中存储的英文值进行相同的操作。
转换后的HTML可以包含在XML-Tags中,而不会干扰XML-Syntax:
$data = "<French>$htmlSpecialFrench</French><English>$htmlSpecialEnglish</English>"
要从$data
获取原始HTML,首先必须使用您的函数提取所选语言的值。然后使用html_entity_decode()
解码转换后的HTML。
答案 4 :(得分:0)
我不知道你的意思,但也许这些帮助:
复制脚本并粘贴到设计器标签中,然后在代码标签中获取脚本(使用Dreamweaver来处理此问题。 例如:
<?php
$params= '<English><h1>Hello</h1></English><French><h1>Bonjour</h1></French>';
print $params;
?>
<h1> for <h1>
</h1> for</h1>