首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从单个XML创建多个XML2筛选

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

Stack Overflow用户
提问于 2019-05-14 15:44:01
回答 2查看 192关注 0票数 2

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

代码语言:javascript
复制
<?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>

我想保存以下两个文件:

代码语言:javascript
复制
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>

如果我这样做的话:

代码语言:javascript
复制
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")

当我创建XML对象的副本时,它继续引用原始对象。有没有一种方法可以在不引用的情况下创建一个新的副本?或者您知道更好的解决问题的方法,使用xml2库?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-14 16:18:03

xml_remove将从在其中找到它们的文档中移除节点。在完成XML之后交换find_all的值并不会有什么帮助,因为它们仍然指向原始文档。复制文档的一种方法似乎是设置了xml_new_root参数的.copy=TRUE函数。以下是一个可以帮助您完成任务的函数

代码语言:javascript
复制
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")

所以我们在这里复制,然后找到副本中的节点,然后删除它们。在这里,我更改为!=比较,只保留传入的语言的值。

票数 3
EN

Stack Overflow用户

发布于 2019-05-14 18:49:02

XSLT为例,这是一种特殊用途的语言,用于将语言参数从R传递到XSLT的XML文件。R可以使用xslt包(xml2的扩展)运行XSLT1.0脚本。

具体来说,您可以使用相同的XSLT脚本为特定的标题节点传递来自R的值。这与将参数传递给另一种著名的特殊用途语言SQL没有什么不同。它的优点还在于XSLT是可移植的(与SQL类似),并且可以在R之外运行以获得相同的结果。

XSLT保存为.xsl文件,这是一个特殊的.xml文件)

代码语言:javascript
复制
<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>

R

代码语言:javascript
复制
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")

Python (演示可移植性)

代码语言:javascript
复制
import lxml.etree as et

# LOAD XML AND XSL SCRIPT
xml = et.parse('Input.xml')
xsl = et.parse('Script.xsl')
transform = et.XSLT(xsl)

# PASS en PARAMETER TO XSLT
n = et.XSLT.strparam("en")
result = transform(xml, lang=n)

with open("Output_en.xml", 'wb') as f:
    f.write(result)

# PASS it PARAMETER TO XSLT
n = et.XSLT.strparam("it")
result = transform(xml, lang=n)

with open("Output_it.xml", 'wb') as f:
    f.write(result)

代码语言:javascript
复制
// LOAD XML AND XSLT
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->load('Input.xml');

$xsl = new DOMDocument('1.0', 'UTF-8');   
$xsl->load('Script.xsl');

// INITIALIZE TRANSFORMER
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);

// SET en PARAMETER VALUE
$proc->setParameter('', 'lang', 'en');
$newXML = $proc->transformToDoc($xml);
file_put_contents('Output_en.xml', $newXML);

// SET en PARAMETER VALUE
$proc->setParameter('', 'lang', 'it');
$newXML = $proc->transformToDoc($xml);
file_put_contents('Output_it.xml', $newXML);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56134189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档