1

XML 形式にしたいデータを含む 2 つのテーブルを次に示します。実物はランダムな行数で2つ以上です。

<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%">&nbsp;</td><td width="8%"><b>210</b>-52.72.810, 770</td></tr>
    <tr><td width="8%">Υποδιευθυντής Φορολογίας</td><td width="8%">&nbsp;</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%">&nbsp;</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>">
  <Προϊστάμενος>&nbsp;</td><td width="8%"><b>210</b>-52.72.810, 770</Προϊστάμενος>
  <Υποδιευθυντής Φορολογίας>&nbsp;</td><td width="8%"><b>210</b>-52.72.810, 770</Υποδιευθυντής Φορολογίας>
</note>

これは可能ですか?どんなコードでも大歓迎です。

4

5 に答える 5

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%">&nbsp;</td><td width="8%"><b>210</b>-52.72.810, 770</td></tr>
    <tr><td width="8%">Υποδιευθυντής Φορολογίας</td><td width="8%">&nbsp;</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%">&nbsp;</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="&lt;b&gt;Δ.Ο.Υ. Α' ΑΘΗΝΩΝ (Α',Β',Γ',ΙΕ',ΚΒ') Κ.Α.: 1101&lt;/b&gt; Αναξαγόρα 6-8, T.K. 100 10 Αθήνα&lt;a name=&quot;aa8inon&quot;&gt;&lt;/a&gt;">
  <Προϊστάμενος> &lt;/td&gt;&lt;td width="8%"&gt;&amp;nbsp;&lt;/td&gt;&lt;td width="8%"&gt;&lt;b&gt;210&lt;/b&gt;-52.72.810, 770&lt;/td&gt;</Προϊστάμενος>
  <Υποδιευθυντής_Φορολογίας> &lt;/td&gt;&lt;td width="8%"&gt;&amp;nbsp;&lt;/td&gt;&lt;td width="8%"&gt;&lt;b&gt;210&lt;/b&gt;-52.72.804&lt;/td&gt;</Υποδιευθυντής_Φορολογίας>
  <Υποδιευθυντής_Ελέγχου> &lt;/td&gt;&lt;td width="8%"&gt;&lt;b&gt;213&lt;/b&gt; 1604121&lt;/td&gt;&lt;td width="8%"&gt;&lt;b&gt;210&lt;/b&gt;-52.72.807&lt;/td&gt;</Υποδιευθυντής_Ελέγχου>
</note>
<note doy="&lt;b&gt;Δ.Ο.Υ. ΚΑΤΟΙΚΩΝ ΕΞΩΤΕΡΙΚΟΥ Κ.Α.: 1125&lt;/b&gt; Μετσόβου 4-T.K.  106 82 Αθήνα">
  <Προϊστάμενος> &lt;/td&gt;&lt;td width="8%"&gt;&lt;b&gt;213&lt;/b&gt; 1607155&lt;/td&gt;&lt;td width="8%"&gt;&lt;b&gt;210&lt;/b&gt;- 8204607&lt;/td&gt;</Προϊστάμενος>
  <Υποδιευθυντής_Φορολογίας> &lt;/td&gt;&lt;td width="8%"&gt;&amp;nbsp;&lt;/td&gt;&lt;td width="8%"&gt;&lt;b&gt;210&lt;/b&gt;- 8204604&lt;/td&gt;</Υποδιευθυντής_Φορολογίας>
</note>
</RootElementName>

【追記】注意事項:

  1. 出力例は、一致しないタグが含まれているという点で混乱を招きました (たとえば、 doy 属性内のマークアップとギリシャ語の名前のタグ内)。サンプル出力をできる限り解釈して、属性内およびギリシャ語の名前の要素内のすべてをテキストに変換しようとしました。つまり、< は & lt; として表されます。および " as & quot; および ' as & apos; しかし、別の可能性として、マークアップを <[!CDATA[ ... ]]> で囲み、その領域の文字を解析しないように XML インタープリターに指示します。
  2. ギリシャ文字を使用して XML 要素に名前を付けることができますが、すべての文字が有効な名前または XML 要素名であるとは限らないことに注意してください。そのため、最初のセル内に表示されるテキストを何らかの方法で制御するか、最初のセル内の無効な文字を明示的に修正する必要があります。コード。http://www.w3schools.com/xml/xml_elements.aspを参照してください。
于 2013-09-08T00:57:05.453 に答える
1

有効な XHTML を XML として解析し、XML スタイルシートを使用して目的の XML 形式に変換できます。HTML は有効な XHTML ではないため、最初にオンライン整頓サイトなどのツールを使用して整頓する必要があります。実行時にこれを行う必要がある場合は、php ライブラリ(サンプル コード付き) もあります。

そのサイトの 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 / &nbsp; td elements -->
                        <xsl:if test="normalize-space(translate(.,'&#xc2;&#xa0;','  '))">
                            <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>

いくつかのメモ:

  • 結果の XML に HTML マークアップを期待するのは奇妙に思えます。XML にデータが含まれており、データが太字でフォーマットされておらず、アンカーが含まれていない。
  • XML 要素名にスペースを含めることは許可されていないため、アンダースコアに置き換えました
  • 整頓されたサイトには UTF-8 を指定する必要があります。そうしないと、ASCII 以外の文字が意味不明になります
  • すべての電話番号を XML に表示することを別の回答で確認するまで、私は最初に質問の XML 形式に固執しようとしました。したがって、私はそれらに別の周囲の要素タグを与えました.
  • XML スタイルシートは言語に依存せず、ほとんどの言語に適用する方法があります。たとえば、php の場合は以下を参照してください。JavaScript の場合もあれば、ブラウザの場合もあります。これは、このスタイルシートを使用して .xhtml を提供すると、ブラウザが XML をレンダリングするためです。しかし、通常はその逆で、XML データの HTML 表現を作成します。いつ、どこで XML を作成する必要があるかについてはよくわかりません。

サンプル 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);
?>
于 2013-09-14T11:08:45.737 に答える
0

いくつかの正規表現で実行できます。これらは、コードが適切にフォーマットされていなくても機能します (ただし、テーブルと td タグは適切にフォーマットする必要があります)。

// 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%">&nbsp;</td><td width="8%"><b>210</b>-52.72.810, 770</td></tr>
        <tr><td width="8%">Υποδιευθυντής Φορολογίας</td><td width="8%">&nbsp;</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%">&nbsp;</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="&lt;b&gt;Δ.Ο.Υ. Α' ΑΘΗΝΩΝ (Α',Β',Γ',ΙΕ',ΚΒ') Κ.Α.: 1101&lt;/b&gt; Αναξαγόρα 6-8, T.K. 100 10 Αθήνα&lt;/a&gt;&lt;a name=&quot;aa8inon&quot;&gt;&lt;/a&gt;">
    <Προϊστάμενος>&nbsp;&lt;b&gt;210&lt;/b&gt;-52.72.810, 770</Προϊστάμενος>
    <Υποδιευθυντής_Φορολογίας>&nbsp;&lt;b&gt;210&lt;/b&gt;-52.72.804</Υποδιευθυντής_Φορολογίας>
    <Υποδιευθυντής_Ελέγχου>&lt;b&gt;213&lt;/b&gt; 1604121&lt;b&gt;210&lt;/b&gt;-52.72.807</Υποδιευθυντής_Ελέγχου>
  </note>
  <note doy="&lt;b&gt;Δ.Ο.Υ. ΚΑΤΟΙΚΩΝ ΕΞΩΤΕΡΙΚΟΥ Κ.Α.: 1125&lt;/b&gt; Μετσόβου 4-T.K.  106 82 Αθήνα">
    <Προϊστάμενος>&lt;b&gt;213&lt;/b&gt; 1604121&lt;b&gt;210&lt;/b&gt;-52.72.807&lt;b&gt;213&lt;/b&gt; 1607155&lt;b&gt;210&lt;/b&gt;- 8204607</Προϊστάμενος>
    <Υποδιευθυντής_Φορολογίας>&nbsp;&lt;b&gt;210&lt;/b&gt;- 8204604</Υποδιευθυντής_Φορολογίας>
  </note>
</root>

コンテンツ内にタグを含めることは有効ではないため、タグの属性とコンテンツの HTML はすべてエスケープされます。ただし、もう一度印刷すると、コンテンツは保持されます。

このソリューションでは、正規表現と、SimpleXML と Dom の両方 (改行とインデントを含む XML のきれいな印刷用) を使用することに注意してください。パフォーマンスの点ではそれほど高速ではありません。Dom 部分をスキップしたい場合は、単に使用できます

echo $xml->asXML()

それ以外の

$dom = dom_import_simplexml($xml)->ownerDocument;
$dom->formatOutput = true;
echo $dom->saveXML();

お役に立てれば。

于 2013-09-09T09:35:44.553 に答える