6

入力xmlファイルが1つあります。

cat sample.xml

<Text>
    &lt;p&gt;ABC &lt;/p&gt;
</Text>

Rスクリプト

library(XML)
doc = xmlTreeParse("sample.xml", useInternal = TRUE)
top<-xmlRoot(doc)

sub("&lt;","<",top[[1]])

上記のpblmを修正するにはどうすればよいですか?

エラーメッセージ:as.vector(x、 "character")のエラー:タイプ'externalptr'をタイプ'character'のベクトルに強制できません

編集:目的は、htmlテーブルを持つxmlの特定のノードにreadHTMLTable()関数を使用することですが、readHTMLTable関数はxmlマークアップを処理できないため、最初に再配置する必要がある>および<にxml markup(&gt;および)があります。&lt;

4

3 に答える 3

7

そして今、あなたの本当の質問への答え:

エンコードされたテーブルを含むsample.xml:

<Text>
&lt;table&gt;
&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;8&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;32&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
</Text>

それを読んでください:

> library(XML)
> doc = xmlTreeParse("sample.xml", useInternal = TRUE)
> top<-xmlRoot(doc)

テキストに変換:

> table=xmlValue(top)
> table
[1] "\n<table>\n<tr><td>1</td><td>2</td></tr>\n<tr><td>2</td><td>8</td></tr>\n<tr><td>4</td><td>32</td></tr>\n</table>\n"

これで、にフィードする準備が整いましたreadHTMLTable。文字列変換は必要ありません:

> readHTMLTable(table)
$`NULL`
  V1 V2
1  1  2
2  2  8
3  4 32

ハウザット?

于 2013-01-31T09:01:23.770 に答える
6

XMLノードのコンテンツ内の文字列を置き換える方法を知りたい場合は、sample.xml提供したファイルを使用して次のコードを確認できます。

## Parse the XML file
doc <- xmlTreeParse("sample.xml", useInternal = TRUE)
## Select the nodes we want to update
nodes <- getNodeSet(doc, "//Text")
## For each node, apply gsub on the content of the node
lapply(nodes, function(n) {
  xmlValue(n) <- gsub("ABC","foobar",xmlValue(n))
})

それはあなたに与えるでしょう:

R> doc
<?xml version="1.0"?>
<Text>
    &lt;p&gt;foobar &lt;/p&gt;
</Text>

ここでは、「ABC」が「foobar」に置き換えられていることがわかります。

ただし、このコードを実現したい置換で試してみると( "&lt;"を "<"に置き換えてください)、明らかに機能しません。

doc <- xmlTreeParse("sample.xml", useInternal = TRUE)
nodes <- getNodeSet(doc, "//Text")
lapply(nodes, function(n) {
  xmlValue(n) <- gsub("&lt;","<",xmlValue(n))
})

あなたに与えるでしょう:

R> doc
<?xml version="1.0"?>
<Text>
    &lt;p&gt;ABC &lt;/p&gt;
</Text>

なんで ?XMLファイルを使用している場合は、主に<、>、および "などの一部の文字が基本XML構文の一部であるため予約されていることを知っておく必要があります。そのため、これらの文字はノードのコンテンツに表示できません。したがって、これらの文字の一種のコーディングであるエンティティに置き換えられます。たとえば、「<」は「&lt;」としてコーディングされ、「&」は「&amp;」としてコーディングされます。

したがって、ここでは、ノードのコンテンツに「<」文字が含まれており、これは自動的に彼のエンティティ「&lt;」に変換されています。コードでやろうとしているのは、「&lt;」を置き換えることです。「<」で戻ってください。これはRが喜んで行いますが、これはノードのテキストコンテンツであるため、XMLパッケージはすぐに「&lt;」に変換し直します。

したがって、達成したいのが文字列「&lt; p&gt; ABC&lt; / p&gt;」を変換することである場合 新しいXMLノード「<p>ABC</ p>」に対しては、そのようにすることはできません。解決策は、テキスト文字列を解析し、そこからノード(ここでは「p」)の名前と名前を検出し、で新しいノードを作成しxmlNode()、テキストコンテンツ「ABC」を指定して、文字列を自分だけのノードに置き換えることです。作成した。

これを行うもう1つの迅速で汚い方法は、最初にXMLを解析せずにファイル内のすべてのエンティティを置き換えることです。このようなもの :

txt <- readLines(file("sample.xml"))
txt <- gsub("&lt;", "<", txt)
txt <- gsub("&gt;", ">", txt)
writeLines(txt, file("sample2.xml"))
doc2 <- xmlTreeParse("sample2.xml", useInternal = TRUE)

これは:

R> doc2
<?xml version="1.0"?>
<Text>
  <p>ABC </p>
</Text>

しかし、これは危険です。なぜなら、「本物の」「&lt;」がある場合だからです。ファイル内のエンティティ、解析は失敗します。

于 2013-01-31T08:36:48.770 に答える
3

ノードの値をでGeしxmlValue、置き換えます。ここでは、ABCをDEFに置き換えます。

> top<-xmlRoot(doc)
> top
<Text>
    &lt;p&gt;ABC &lt;/p&gt;
</Text> 
> xmlValue(top)=sub("ABC","DEF",xmlValue(top))
> top
<Text>
    &lt;p&gt;DEF &lt;/p&gt;
</Text> 

<を置き換えようとしない理由は、これらの文字シーケンスがある時点でXMLコードによって解釈されるためです。

> substr(xmlValue(top),6,6)=="<"
[1] TRUE

いくつかのオプションや他のXMLパッケージ関数をいじってみましたが、それらの解釈xmlTreeParseをやめられないようです...xmlValue

于 2013-01-31T08:27:30.733 に答える