R 从单个XML创建多个XML2筛选

R 从单个XML创建多个XML2筛选,r,xml,xml2,R,Xml,Xml2,使用xml2包,我想从一个XML文件开始编写两个XML文件——一个用于语言。例如,我有以下XML文件: <?xml version="1.0" encoding="UTF-8"?> <books> <book> <title xml:lang="it">Title IT</title> <title xml:lang="en">Title EN</title> <author&g

使用xml2包,我想从一个XML文件开始编写两个XML文件——一个用于语言。例如,我有以下XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<books>
  <book>
    <title xml:lang="it">Title IT</title>
    <title xml:lang="en">Title EN</title>
    <author>Author</author>
  </book>
</books>

标题
标题EN
作者
我想保存以下两个文件:

FILE IT
<?xml version="1.0" encoding="UTF-8"?>
<books>
  <book>
    <title xml:lang="it">Title IT</title>
    <author>Author</author>
  </book>
</books>

FILE EN
<?xml version="1.0" encoding="UTF-8"?>
<books>
  <book>
    <title xml:lang="en">Title EN</title>
    <author>Author</author>
  </book>
</books>
把它归档
标题
作者
锉刀
标题EN
作者
如果我这样做:

txt <- "<books><book><title xml:lang='it'>Title IT</title><title xml:lang='en'>Title EN</title><author>Author</author></book></books>"
XML <- xml2::read_xml(txt)

it <- xml2::xml_find_all(XML, "//*[@xml:lang = 'it']")
en <- xml2::xml_find_all(XML, "//*[@xml:lang = 'en']")


XML_orig <- XML
xml2::xml_remove(en)
xml2::write_xml(XML, file = "book_it.xml")

XML <- XML_orig
xml2::xml_remove(it)
xml2::write_xml(XML, file = "book_en.xml")

txtxml\u remove
将从找到节点的文档中删除节点。在完成“全部查找”之后交换
XML
的值并没有真正的帮助,因为它们仍然指向原始文档。复制文档的一种方法似乎是设置了
.copy=TRUE
参数的
xml\u new\u root
函数。这里有一个函数可以帮助您完成任务

keeplang <- function(XML, lang) {
  nodepath <- paste0("//*[@xml:lang != '", lang, "']")
  filepath <- paste0("book_", lang, ".xml")
  XML <- xml_new_root(XML, .copy = TRUE)  
  nodes <- xml2::xml_find_all(XML, nodepath)
  xml2::xml_remove(nodes)
  xml2::write_xml(XML, file = filepath)
}

keeplang(XML, "it")
keeplang(XML, "en")
keeplang考虑一下,这是一种专门用于转换XML文件的语言,您可以在其中将语言参数en和it从R传递到XSLT。R可以使用
XSLT
包(扩展
xml2
)运行XSLT1.0脚本

具体地说,您可以使用相同的XSLT脚本将R中的值传递给特定的标题节点。这与将参数传递给另一种众所周知的特殊用途语言SQL没有什么不同。XSLT的优点也在于它是可移植的(和SQL一样),并且可以在R之外运行以产生相同的结果

XSLT另存为.xsl文件,一个特殊的.xml文件)

PHP

//加载XML和XSLT
$xml=新的DOMDocument('1.0','UTF-8');
$xml->load('Input.xml');
$xsl=新的DOMDocument('1.0','UTF-8');
$xsl->load('Script.xsl');
//初始化变压器
$proc=新的XSLTProcessor;
$proc->importStyleSheet($xsl);
//设置参数值
$proc->setParameter(''lang','en');
$newXML=$proc->transformToDoc($xml);
文件内容('Output_en.xml',$newXML);
//设置参数值
$proc->setParameter(''lang','it');
$newXML=$proc->transformToDoc($xml);
文件内容('Output_it.xml',$newXML);

感谢您的努力!我将在将来深入研究XLST,现在在我的实际案例中使用它可能会有点痛苦!但XLST对我的产品来说很有前途。XSLT确实需要一些诀窍,但传递参数值非常酷。这是我第一次在R做这件事,所以谢谢你的提问。我正在将其添加到我的解决方案库中。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="lang" />

  <!-- IDENTITY TRANSFORM -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="book">
    <xsl:copy>
        <xsl:copy-of select="title[@xml:lang = $lang]"/>
        <xsl:copy-of select="author"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
library(xml2)
library(xslt)

doc <- read_xml("Input.xml", package = "xslt")
style <- read_xml("Script.xsl", package = "xslt")

# en LANGUAGE
new_xml <- xml_xslt(doc, style, params=list(lang="en"))   
write_xml(new_xml, "Output_en.xml")

# it LANGUAGE
new_xml <- xml_xslt(doc, style, params=list(lang="it"))   
write_xml(new_xml, "Output_it.xml")