这是两个包含我希望以XML格式提供的数据的表。实际的东西是两个以上,随机行数。
<table width="100%" align="center" class="mytable" border="1" cellspacing="1">
<tr><td width="100%"><b>Δ.Ο.Υ. Α' ΑΘΗΝΩΝ (Α',Β',Γ',ΙΕ',ΚΒ') Κ.Α.: 1101</b> Αναξαγόρα 6-8, T.K. 100 10 Αθήνα</a><a name="aa8inon"></a></td></tr>
<tr><td width="8%">Προϊστάμενος</td><td width="8%"> </td><td width="8%"><b>210</b>-52.72.810, 770</td></tr>
<tr><td width="8%">Υποδιευθυντής Φορολογίας</td><td width="8%"> </td><td width="8%"><b>210</b>-52.72.804</td></tr>
<tr><td width="8%">Υποδιευθυντής Ελέγχου</td><td width="8%"><b>213</b> 1604121</td><td width="8%"><b>210</b>-52.72.807</td></tr>
</table>
<table width="100%" align="center" class="mytable" border="1" cellspacing="1">
<tr><td width="100%"><b>Δ.Ο.Υ. ΚΑΤΟΙΚΩΝ ΕΞΩΤΕΡΙΚΟΥ Κ.Α.: 1125</b> Μετσόβου 4-T.K. 106 82 Αθήνα</td></tr>
<tr><td width="8%">Προϊστάμενος</td><td width="8%"><b>213</b> 1607155</td><td width="8%"><b>210</b>- 8204607</td></tr>
<tr><td width="8%">Υποδιευθυντής Φορολογίας</td><td width="8%"> </td><td width="8%"><b>210</b>- 8204604</td></tr>
</table>
table标记下面的第一行是根元素,所有其他行都是子元素。如果我在正确命名元素时犯了一些错误,请原谅我。
例如,在您看到的第一个<tr><td>
之间
<b>Δ.Ο.Υ. Α' ΑΘΗΝΩΝ (Α',Β',Γ',ΙΕ',ΚΒ') Κ.Α.: 1101</b> Αναξαγόρα 6-8, T.K. 100 10 Αθήνα</a><a name="aa8inon"></a>
这将是根元素中的属性名称。
以下行<td></td>
中的第一个Προϊστάμενος
是子元素,从<td>
开始,直到</td>
的最后<tr>
为数据这个子元素。
这就是我想要的
<note doy="<b>Δ.Ο.Υ. Α' ΑΘΗΝΩΝ (Α',Β',Γ',ΙΕ',ΚΒ') Κ.Α.: 1101</b> Αναξαγόρα 6-8, T.K. 100 10 Αθήνα</a><a name="aa8inon"></a>">
<Προϊστάμενος> </td><td width="8%"><b>210</b>-52.72.810, 770</Προϊστάμενος>
<Υποδιευθυντής Φορολογίας> </td><td width="8%"><b>210</b>-52.72.810, 770</Υποδιευθυντής Φορολογίας>
</note>
这可能吗?任何代码都表示赞赏。
答案 0 :(得分:8)
首先,我应该注意您要输出的XML似乎无效。
您可以使用优秀的querypath库(http://querypath.org/),最终您可以将相同的逻辑从PHP应用到Javascript(使用JQuery的选择器引擎)
这是一段代码,可以从您的输入中生成有效的XML (顺便说一下,我是希腊语,所以对我来说更有意义):
libxml_use_internal_errors(true);
$html = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body><table width="100%" align="center" class="mytable" border="1" cellspacing="1">
<tr><td width="100%"><b>Δ.Ο.Υ. Α\' ΑΘΗΝΩΝ (Α\',Β\',Γ\',ΙΕ\',ΚΒ\') Κ.Α.: 1101</b> Αναξαγόρα 6-8, T.K. 100 10 Αθήνα</a><a name="aa8inon"></a></td></tr>
<tr><td width="8%">Προϊστάμενος</td><td width="8%"> </td><td width="8%"><b>210</b>-52.72.810, 770</td></tr>
<tr><td width="8%">Υποδιευθυντής Φορολογίας</td><td width="8%"> </td><td width="8%"><b>210</b>-52.72.804</td></tr>
<tr><td width="8%">Υποδιευθυντής Ελέγχου</td><td width="8%"><b>213</b> 1604121</td><td width="8%"><b>210</b>-52.72.807</td></tr>
</table>
<table width="100%" align="center" class="mytable" border="1" cellspacing="1">
<tr><td width="100%"><b>Δ.Ο.Υ. ΚΑΤΟΙΚΩΝ ΕΞΩΤΕΡΙΚΟΥ Κ.Α.: 1125</b> Μετσόβου 4-T.K. 106 82 Αθήνα</td></tr>
<tr><td width="8%">Προϊστάμενος</td><td width="8%"><b>213</b> 1607155</td><td width="8%"><b>210</b>- 8204607</td></tr>
<tr><td width="8%">Υποδιευθυντής Φορολογίας</td><td width="8%"> </td><td width="8%"><b>210</b>- 8204604</td></tr>
</table></body></html>';
$results = qp($html, 'table.mytable');
$xml = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><notes/>');
foreach( $results as $result ) {
$note = $xml->addChild("note");
foreach( $result->children('tr') as $idx => $tr ) {
if( $idx == 0 ) {
$note->addAttribute("doy", $tr->children('td')->text());
continue;
}
$tds = $tr->children('td');
foreach( $tds as $tidx => $td ) {
if( $tidx == 0 ) {
$person = $note->addChild("person");
$person->addAttribute("title", trim($td->text()));
continue;
}
$phoneValue = $td->text();
$phoneValue = str_replace( array(" ", ".", "-", "\xc2\xa0"), "", $phoneValue );
if( $phoneValue != '' )
$phone = $person->addChild("phone", $phoneValue);
}
}
}
$dom = dom_import_simplexml($xml)->ownerDocument;
$dom->formatOutput = true;
echo $dom->saveXML();
输出:
<?xml version="1.0" encoding="UTF-8"?>
<notes>
<note doy="Δ.Ο.Υ. Α' ΑΘΗΝΩΝ (Α',Β',Γ',ΙΕ',ΚΒ') Κ.Α.: 1101 Αναξαγόρα 6-8, T.K. 100 10 Αθήνα">
<person title="Προϊστάμενος">
<phone>2105272810,770</phone>
</person>
<person title="Υποδιευθυντής Φορολογίας">
<phone>2105272804</phone>
</person>
<person title="Υποδιευθυντής Ελέγχου">
<phone>2131604121</phone>
<phone>2105272807</phone>
</person>
</note>
<note doy="Δ.Ο.Υ. ΚΑΤΟΙΚΩΝ ΕΞΩΤΕΡΙΚΟΥ Κ.Α.: 1125 Μετσόβου 4-T.K. 106 82 Αθήνα">
<person title="Προϊστάμενος">
<phone>2131607155</phone>
<phone>2108204607</phone>
</person>
<person title="Υποδιευθυντής Φορολογίας">
<phone>2108204604</phone>
</person>
</note>
</notes>
请注意:我已将您的html代码包装在<html><head><body>
标记中,添加了<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
标记,以帮助querypath识别编码。如果您需要更多信息,请参阅https://github.com/technosophos/querypath/issues/94。
如果您坚持创建已粘贴在问题中的XML,则可以相应地更改样本。
此外,querypath奇怪地将
转换为0xC2 0xA0 (c2a0)
(Unicode字符无中断空格)(http://www.fileformat.info/info/unicode/char/a0/index.htm),因此"\xc2\xa0"
中的str_replace
< / p>
答案 1 :(得分:2)
回顾过去,我不知道你的问题是关于php还是javascript,但这里是Javascript的答案。只需将其保存到HTML文件并将其加载到新的浏览器窗口中即可查看输出。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<table width="100%" align="center" class="mytable" border="1" cellspacing="1">
<tr><td width="100%"><b>Δ.Ο.Υ. Α' ΑΘΗΝΩΝ (Α',Β',Γ',ΙΕ',ΚΒ') Κ.Α.: 1101</b> Αναξαγόρα 6-8, T.K. 100 10 Αθήνα</a><a name="aa8inon"></a></td></tr>
<tr><td width="8%">Προϊστάμενος</td><td width="8%"> </td><td width="8%"><b>210</b>-52.72.810, 770</td></tr>
<tr><td width="8%">Υποδιευθυντής Φορολογίας</td><td width="8%"> </td><td width="8%"><b>210</b>-52.72.804</td></tr>
<tr><td width="8%">Υποδιευθυντής Ελέγχου</td><td width="8%"><b>213</b> 1604121</td><td width="8%"><b>210</b>-52.72.807</td></tr>
</table>
<table width="100%" align="center" class="mytable" border="1" cellspacing="1">
<tr><td width="100%"><b>Δ.Ο.Υ. ΚΑΤΟΙΚΩΝ ΕΞΩΤΕΡΙΚΟΥ Κ.Α.: 1125</b> Μετσόβου 4-T.K. 106 82 Αθήνα</td></tr>
<tr><td width="8%">Προϊστάμενος</td><td width="8%"><b>213</b> 1607155</td><td width="8%"><b>210</b>- 8204607</td></tr>
<tr><td width="8%">Υποδιευθυντής Φορολογίας</td><td width="8%"> </td><td width="8%"><b>210</b>- 8204604</td></tr>
</table>
<textarea id="output" rows="24" cols="140"></textarea>
</body>
<script type="text/javascript">
var tables=document.getElementsByTagName("table");
var doc, note, el, elName, txt,txtContent;
doc=document.implementation.createDocument("AnyNamespaceYouWantForYourXML","RootElementName"); //In older versions of IE, I believe you'll have to resort to an ActiveX object
for(var t =0; t<tables.length;t++){
el=doc.createElement("note");
note=doc.documentElement.appendChild(el);
rows=tables[t].getElementsByTagName("tr");
for(var r=0; r<rows.length; r++){
var tds=rows[r].getElementsByTagName("td");
if(r==0){
note.setAttribute("doy",tds[0].innerHTML); //Unlike in your example output, the real output will have 'special' characters correctly html encoded
} else {
elName=tds[0].innerText;
elName=elName.trim(); //You probably want to discard leading or trailing whitespace
elName=elName.replace(/[\s]+/g,"_"); //XML element names cannot contain spaces, so replace with underscores
//There are other rules relating to valid XML element names which you may need to add here. Greek letters should be fine.
el=doc.createElement(elName);
//It wasn't clear from your example whether you wanted the xml element to contain the text of the html or some text and a td element
//The first case seemed more likely, so here it is
txtContent=" </td>";
for(var d=1;d<tds.length;d++){
txtContent+=tds[d].outerHTML;
}
txt=doc.createTextNode(txtContent);
el.appendChild(txt); //Put the text in the element
note.appendChild(el); //Add the element to the note
}
}
}
console.log(doc); //Check the console, you have a useful XML document object
document.getElementById("output").value=xml2Str(doc.documentElement); //Output a string representation
function xml2Str(xmlNode) {
try {
// Pretty printing available?
return XML((new XMLSerializer()).serializeToString(xmlNode)).toXMLString();
}
catch (e) {}
try {
// Gecko- and Webkit-based browsers (Firefox, Chrome), Opera.
return (new XMLSerializer()).serializeToString(xmlNode).replace(/<([^\/])/g,"\n<$1");
}
catch (e) {}
try {
// Internet Explorer.
return xmlNode.xml.replace(/<([^\/])/g,"<\1");
}
catch (e) {}
//Other browsers without XML Serializer
alert('Xmlserializer not supported');
return false;
}
</script>
</html>
示例输出(手动添加缩进):
<RootElementName xmlns="AnyNamespaceYouWantForYourXML">
<note doy="<b>Δ.Ο.Υ. Α' ΑΘΗΝΩΝ (Α',Β',Γ',ΙΕ',ΚΒ') Κ.Α.: 1101</b> Αναξαγόρα 6-8, T.K. 100 10 Αθήνα<a name="aa8inon"></a>">
<Προϊστάμενος> </td><td width="8%">&nbsp;</td><td width="8%"><b>210</b>-52.72.810, 770</td></Προϊστάμενος>
<Υποδιευθυντής_Φορολογίας> </td><td width="8%">&nbsp;</td><td width="8%"><b>210</b>-52.72.804</td></Υποδιευθυντής_Φορολογίας>
<Υποδιευθυντής_Ελέγχου> </td><td width="8%"><b>213</b> 1604121</td><td width="8%"><b>210</b>-52.72.807</td></Υποδιευθυντής_Ελέγχου>
</note>
<note doy="<b>Δ.Ο.Υ. ΚΑΤΟΙΚΩΝ ΕΞΩΤΕΡΙΚΟΥ Κ.Α.: 1125</b> Μετσόβου 4-T.K. 106 82 Αθήνα">
<Προϊστάμενος> </td><td width="8%"><b>213</b> 1607155</td><td width="8%"><b>210</b>- 8204607</td></Προϊστάμενος>
<Υποδιευθυντής_Φορολογίας> </td><td width="8%">&nbsp;</td><td width="8%"><b>210</b>- 8204604</td></Υποδιευθυντής_Φορολογίας>
</note>
</RootElementName>
[编辑]注意事项:
答案 2 :(得分:1)
您可以将有效的XHTML解析为XML,并使用XML样式表将其转换为所需的XML格式。 由于HTML不是有效的XHTML,因此您必须首先使用工具整理它,例如an online tidy site。如果您需要在运行时执行此操作,那么还有一个php library(带sample code)。
我整理了该网站上的HTML,并将以下样式表应用于其中:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:template match="/xhtml:html/xhtml:body">
<xsl:element name="notes">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="xhtml:table">
<xsl:element name="note">
<xsl:attribute name="doy">
<xsl:value-of select="xhtml:tr[1]/xhtml:td" />
</xsl:attribute>
<xsl:for-each select="xhtml:tr[position() != 1]">
<xsl:element name="{translate(xhtml:td,' ','_')}">
<xsl:for-each select="xhtml:td[position() != 1]">
<!-- filter out empty / td elements -->
<xsl:if test="normalize-space(translate(.,' ',' '))">
<xsl:element name="τηλέφωνο">
<xsl:value-of select="." />
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这会产生:
<notes>
<note
doy="Δ.Ο.Υ. Α' ΑΘΗΝΩΝ (Α',Β',Γ',ΙΕ',ΚΒ') Κ.Α.: 1101 Αναξαγόρα 6-8, T.K. 100 10 Αθήνα">
<Προϊστάμενος>
<τηλέφωνο>210-52.72.810, 770</τηλέφωνο>
</Προϊστάμενος>
<Υποδιευθυντής_Φορολογίας>
<τηλέφωνο>210-52.72.804</τηλέφωνο>
</Υποδιευθυντής_Φορολογίας>
<Υποδιευθυντής_Ελέγχου>
<τηλέφωνο>213 1604121</τηλέφωνο>
<τηλέφωνο>210-52.72.807</τηλέφωνο>
</Υποδιευθυντής_Ελέγχου>
</note>
<note
doy="Δ.Ο.Υ. ΚΑΤΟΙΚΩΝ ΕΞΩΤΕΡΙΚΟΥ Κ.Α.: 1125 Μετσόβου 4-T.K. 106 82 Αθήνα">
<Προϊστάμενος>
<τηλέφωνο>213 1607155</τηλέφωνο>
<τηλέφωνο>210- 8204607</τηλέφωνο>
</Προϊστάμενος>
<Υποδιευθυντής_Φορολογίας>
<τηλέφωνο>210- 8204604</τηλέφωνο>
</Υποδιευθυντής_Φορολογίας>
</note>
</notes>
一些注意事项:
示例php代码:
<?php
$xhtml_file = 'doc.xhtml';
$xsl_file = 'doc.xsl';
$doc = new DOMDocument();
$xsl = new XSLTProcessor();
$doc->load($xsl_file);
$xsl->importStyleSheet($doc);
$doc->load($xhtml_file);
echo $xsl->transformToXML($doc);
?>
答案 3 :(得分:0)
我自己不是php编码器,对任何错误道歉。我使用[1]作为参考,并快速更改了答案,以便接近您的问题:
代码是一个粗略的想法:
<?php
# Create new DOM object
$domOb = new DOMDocument();
# Grab your HTML file
$html = $domOb->loadHTMLFile(sections.html);
# Remove whitespace
$domOb->preserveWhiteSpace = false;
# Set the container tag
$container = $domOb->getElementsByTagName('table');
# Loop through td values
foreach ($container as $row)
{
# Grab all <td>
$items = $row->getElementsByTagName('td');
}
?>
完全回答这个问题的演变:
这样,几乎直接来自该来源[1],$container
包含所有表格,$items
具有<td>
元素内容。
我想你可以使用一些php,所以现在做以下事情并不是一个大技巧(这里只有伪代码,对不起):
1) Take one table item from `$container` with that `foreach`
2) Take first td item, write the needed xml tag `<note doy="`
3) Print td content there
4) Close tag `">`
5) Print the rest of the rows, adding the <td> tags manually to the sides (I suppose this code removes them
6) Add trailing `</node>` tag and iterate to next one on `$container`
抱歉,我的php技能等于零,尝试用这些来管理,或者如果其他人可以改进这一点,请随意使用我的开头作为来源并做出新的答案。我只是想帮助@Kaoukkos,如果我不能给出最完整的答案而另一个人可以,我不想要任何分数。
我们需要的是不要用foreach迭代它,而是用其他方式 ,你可以说 2-4到第一行和5到其余内容 就是这样,伙计们!
我的消息来源:
答案 4 :(得分:0)
可以使用一些正则表达式来完成。即使您的代码格式不正确(但您的表格和标签必须正确格式化),这些工作仍然有效。
// your original string
$string = <<<heredoc
<table width="100%" align="center" class="mytable" border="1" cellspacing="1">
<tr><td width="100%"><b>Δ.Ο.Υ. Α' ΑΘΗΝΩΝ (Α',Β',Γ',ΙΕ',ΚΒ') Κ.Α.: 1101</b> Αναξαγόρα 6-8, T.K. 100 10 Αθήνα</a><a name="aa8inon"></a></td></tr>
<tr><td width="8%">Προϊστάμενος</td><td width="8%"> </td><td width="8%"><b>210</b>-52.72.810, 770</td></tr>
<tr><td width="8%">Υποδιευθυντής Φορολογίας</td><td width="8%"> </td><td width="8%"><b>210</b>-52.72.804</td></tr>
<tr><td width="8%">Υποδιευθυντής Ελέγχου</td><td width="8%"><b>213</b> 1604121</td><td width="8%"><b>210</b>-52.72.807</td></tr>
</table>
<table width="100%" align="center" class="mytable" border="1" cellspacing="1">
<tr><td width="100%"><b>Δ.Ο.Υ. ΚΑΤΟΙΚΩΝ ΕΞΩΤΕΡΙΚΟΥ Κ.Α.: 1125</b> Μετσόβου 4-T.K. 106 82 Αθήνα</td></tr>
<tr><td width="8%">Προϊστάμενος</td><td width="8%"><b>213</b> 1607155</td><td width="8%"><b>210</b>- 8204607</td></tr>
<tr><td width="8%">Υποδιευθυντής Φορολογίας</td><td width="8%"> </td><td width="8%"><b>210</b>- 8204604</td></tr>
</table>
heredoc;
$patternTable = "/<table(.+?)table>/s"; // simple regExp for table tags
$patternTd = '/<td[^>]*>(.+?)<\/td>/s'; // simple regExp for individual tds
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><root/>');
preg_match_all($patternTable, $string, $matches);
for($i=0; $i<sizeof($matches[1]); $i++){
$tds = array();
$attribute = "";
$content = "";
$tagName = "";
preg_match_all($patternTd,$matches[1][$i], $tds);
for($j=0; $j<sizeof($tds[1]); $j++){
if($j==0){ // first TD, add as attribute of note, taking the CONTENT of the td
$attribute = $tds[1][$j];
$note = $xml->addChild("note");
$note->addAttribute("doy", $attribute);
} else { // other tds
// there are 3 tds, the first is the name of the tag, the other two the contents
if($j %3 == 1){
if($tagName != ""){
$note->addChild($tagName, $tagContent);
$tagContent = "";
}
$tagName = str_replace(" ", "_", $tds[1][$j]);
} else {
$tagContent.= $tds[1][$j];
}
}
}
$note->addChild($tagName, $tagContent); // add the last opened node
}
$dom = dom_import_simplexml($xml)->ownerDocument;
$dom->formatOutput = true;
echo $dom->saveXML();
这个脚本的结果是:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<note doy="<b>Δ.Ο.Υ. Α' ΑΘΗΝΩΝ (Α',Β',Γ',ΙΕ',ΚΒ') Κ.Α.: 1101</b> Αναξαγόρα 6-8, T.K. 100 10 Αθήνα</a><a name="aa8inon"></a>">
<Προϊστάμενος> <b>210</b>-52.72.810, 770</Προϊστάμενος>
<Υποδιευθυντής_Φορολογίας> <b>210</b>-52.72.804</Υποδιευθυντής_Φορολογίας>
<Υποδιευθυντής_Ελέγχου><b>213</b> 1604121<b>210</b>-52.72.807</Υποδιευθυντής_Ελέγχου>
</note>
<note doy="<b>Δ.Ο.Υ. ΚΑΤΟΙΚΩΝ ΕΞΩΤΕΡΙΚΟΥ Κ.Α.: 1125</b> Μετσόβου 4-T.K. 106 82 Αθήνα">
<Προϊστάμενος><b>213</b> 1604121<b>210</b>-52.72.807<b>213</b> 1607155<b>210</b>- 8204607</Προϊστάμενος>
<Υποδιευθυντής_Φορολογίας> <b>210</b>- 8204604</Υποδιευθυντής_Φορολογίας>
</note>
</root>
标签的属性和内容中的所有HTML都会被转义,因为在内容中包含标签无效。但如果再次打印出来,它将保留您的内容。
请记住,此解决方案使用正则表达式以及SimpleXML和Dom(对于带有换行符和缩进的XML的漂亮打印) - 在性能方面不会非常快。如果你想跳过Dom部分,你可以使用
echo $xml->asXML()
而不是
$dom = dom_import_simplexml($xml)->ownerDocument;
$dom->formatOutput = true;
echo $dom->saveXML();
希望这有帮助。