Как объединить определенный тип узлов в XML-данных в R?
У меня есть XML-файл книги. Главное дерево имеет уровни Body/Pagecolumn/Region/Paragraph/Line/Word. Однако меня не интересует уровень Line. Есть ли способ объединить уровень Line, не разрушая уровень Word в R, используя пакет XML или любой другой пакет? После преобразования основным деревом будет Body/Pagecolumn/Region/Paragraph/Word
Пример данных XML приведен ниже:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE DjVuXML>
<DjVuXML>
<BODY>
<OBJECT data="file://localhost//book1.djvu" height="1650" type="image/x.djvu" usemap="book1.djvu" width="1275">
<PARAM name="PAGE" value="book1_001.djvu"/>
<PARAM name="DPI" value="300"/>
<HIDDENTEXT>
<PAGECOLUMN>
<REGION>
<PARAGRAPH>
<LINE>
<WORD coords="1,2,3,4,5">Title</WORD>
</LINE>
</PARAGRAPH>
</REGION>
</PAGECOLUMN>
<PAGECOLUMN>
<REGION>
<PARAGRAPH>
<LINE>
<WORD coords="30,564,90,545,559">This</WORD>
<WORD coords="97,559,109,545,559">is</WORD>
<WORD coords="115,564,162,545,559">a</WORD>
</LINE>
</PARAGRAPH>
<PARAGRAPH>
<LINE>
<WORD coords="30,589,80,570,584">First</WORD>
<WORD coords="88,584,115,570,584">line</WORD>
<WORD coords="123,584,146,574,584">is</WORD>
</LINE>
<LINE>
<WORD coords="30,614,90,598,609">Second</WORD>
<WORD coords="97,609,143,595,609">line</WORD>
<WORD coords="148,614,168,595,609">is</WORD>
</LINE>
<LINE>
<WORD coords="30,640,56,626,640">Third</WORD>
<WORD coords="63,640,95,626,640">line</WORD>
<WORD coords="101,640,128,626,640">is</WORD>
</LINE>
</PARAGRAPH>
</REGION>
</PAGECOLUMN>
</HIDDENTEXT>
</OBJECT>
<MAP name="book1.djvu"/>
</BODY>
</DjVuXML>
Благодарю.
3 ответа
Мне нравятся простые решения регулярных выражений, и в этом случае они, вероятно, путь. В общем с XML
мы хотели бы использовать XSLT
, Это язык для преобразования XML
, Есть пакет R Sxslt
который может быть использован для преобразования XML
, Идея состоит в том, чтобы определить 2 шаблона:
- Первый шаблон - это то, что называется преобразованием идентичности. Это копирует все атрибуты и узлы. Если для конкретного элемента есть более подходящий шаблон, xslt будет использовать его вместо этого.
- Затем мы объявили шаблон более актуальным для LINE. Это ничего не делает. Таким образом, для всех узлов и атрибутов, кроме LINE, преобразование выполняет копирование.
Вот мой код:
# install package if needed
# install.packages('Sxslt', repos = "http://www.omegahat.org/R")
require(Sxslt)
# define a transformation
sltTemp <- '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="LINE">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>'
# assume your XML is text variable named xdata
# you can also work on a parsed file if you like
# xD <- xmlParse(xdata)
# xsltApplyStyleSheet(xD, sltTemp)
# gives same result
require(XML)
newxdata <- saveXML(xsltApplyStyleSheet(xdata, sltTemp))
xmlParse(newxdata)
<?xml version="1.0"?>
<DjVuXML>
<BODY>
<OBJECT data="file://localhost//book1.djvu" height="1650" type="image/x.djvu" usemap="book1.djvu" width="1275">
<PARAM name="PAGE" value="book1_001.djvu"/>
<PARAM name="DPI" value="300"/>
<HIDDENTEXT>
<PAGECOLUMN>
<REGION>
<PARAGRAPH>
<WORD coords="1,2,3,4,5">Title</WORD>
</PARAGRAPH>
</REGION>
</PAGECOLUMN>
<PAGECOLUMN>
<REGION>
<PARAGRAPH>
<WORD coords="30,290,65,276,290">This</WORD>
<WORD coords="73,290,84,276,290">is</WORD>
<WORD coords="92,290,100,280,290">a</WORD>
</PARAGRAPH>
<PARAGRAPH>
<WORD coords="30,290,65,276,290">First</WORD>
<WORD coords="73,290,84,276,290">line</WORD>
<WORD coords="92,290,100,280,290">is</WORD>
<WORD coords="30,290,65,276,290">Second</WORD>
<WORD coords="73,290,84,276,290">line</WORD>
<WORD coords="92,290,100,280,290">is</WORD>
<WORD coords="30,290,65,276,290">Third</WORD>
<WORD coords="73,290,84,276,290">line</WORD>
<WORD coords="92,290,100,280,290">is</WORD>
</PARAGRAPH>
</REGION>
</PAGECOLUMN>
</HIDDENTEXT>
</OBJECT>
<MAP name="book1.djvu"/>
</BODY>
</DjVuXML>
Правильный способ будет использовать xml
упаковать и сделать узлы слияния.
Тем не менее, для предоставленного вами образца XML, вы можете обойтись простым gsub
(найти и заменить).
Что-то вроде:
xmlfile <- readLines("test.xml")
newfile <- gsub("<LINE>|</LINE>", "", xmlfile)
И иди оттуда.
Аналогичное решение с использованием grepl
удалить все строки:
ll <- readLines(textConnection(txt))
ll <- ll[!grepl("<LINE>|</LINE>" ,ll)]
txt <- paste(ll, "\n", collapse="")
xmlParse(txt,asText=TRUE)