草庐IT

php - 包装一组 XML 节点

coder 2024-04-13 原文

我正在使用 PHP5,我需要将 XML 转换为以下形式:

<list>
    <item label="(1)">some text</item>
    <item label="(2)">
        <anotherNode>some text</anotherNode
        <item label="a">some text</item>
        <item label="b">some text</item>          
    </item>
</list>

变成这样:

<list>
    <item label="(1)">some text</item>
    <item label="(2)">
        <anotherNode>some text</anotherNode>
        <list> <!-- opening new wrapper node-->
            <item label="a">some text</item>
            <item label="b">some text</item>
        </list> <!-- closing new wrapper node-->
    </item>
</list> 

正如您在上面看到的,我需要向任何尚未被“列表”节点包装的“项目”节点添加一个包装器节点。

将源 xml 转换为目标 xml 的可能解决方案是什么?

更新:

注1:任意一个或一组<item>节点需要用 <list> 包裹节点,如果它还没有包装。

注2:需要保持内容的顺序。

注3: 如果有<item> <anotherNode> 之前和之后的节点. 它应该改变这个:

<list>
    <item label="(1)">some text</item>
    <item label="(2)">
        <item label="a">some text</item>
        <item label="b">some text</item>          
        <anotherNode>some text</anotherNode>
        <item label="c">some text</item>
        <item label="d">some text</item>          
    </item>
</list>

进入这个:

<list>
    <item label="(1)">some text</item>
    <item label="(2)">
        <list> <!-- opening new wrapper node-->
            <item label="a">some text</item>
            <item label="b">some text</item>          
        </list> <!-- closing new wrapper node-->
        <anotherNode>some text</anotherNode>
        <list> <!-- opening new wrapper node-->
            <item label="c">some text</item>
            <item label="d">some text</item>
        </list> <!-- closing new wrapper node-->
    </item>
</list>

谢谢,

最佳答案

这个转换:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="item/item[1]">
  <list>
   <xsl:apply-templates mode="copy"
    select=".| following-sibling::item"/>
  </list>
 </xsl:template>

 <xsl:template match="item" mode="copy">
  <xsl:call-template name="identity"/>
 </xsl:template>

 <xsl:template match="item/item[not(position()=1)]"/>
</xsl:stylesheet>

应用于提供的 XML 文档时:

<list>
    <item label="(1)">some text</item>
    <item label="(2)">
        <anotherNode>some text</anotherNode>
        <item label="a">some text</item>
        <item label="b">some text</item>
    </item>
</list>

产生想要的、正确的结果:

<list>
   <item label="(1)">some text</item>
   <item label="(2)">
      <anotherNode>some text</anotherNode>
      <list>
         <item label="a">some text</item>
         <item label="b">some text</item>
      </list>
   </item>
</list>

请注意:

  1. 身份规则的使用和覆盖

  2. 抑制某些元素。

  3. 使用不同的模式处理某些元素。

更新:

OP 添加了额外的要求:

"如果在 anothernode 之前和之后有 item 元素,则必须包含每个这样的 item 元素组在单独的列表中”

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kfollnonitem" match="item"
  use="generate-id(preceding-sibling::*[not(self::item)][1])"/>

 <xsl:key name="kprecnonitem" match="item"
  use="generate-id(following-sibling::*[not(self::item)][1])"/>

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

 <xsl:template match="*[not(self::list)]/item[1]">
  <list>
   <xsl:apply-templates mode="copy"
    select="key('kprecnonitem',
                 generate-id(following-sibling::*[not(self::item)][1])
                 )"/>
  </list>
 </xsl:template>

 <xsl:template match=
  "*[not(self::list) and item]/*[not(self::item)]">
  <xsl:call-template name="identity"/>

  <list>
    <xsl:apply-templates mode="copy"
     select="key('kfollnonitem', generate-id())"/>
  </list>
 </xsl:template>

 <xsl:template match="item" mode="copy">
  <xsl:call-template name="identity"/>
 </xsl:template>

 <xsl:template match="item/item[not(position()=1)]"/>
</xsl:stylesheet>

当对以下 XML 文档执行此转换时:

<list>
    <item label="(1)">some text</item>
    <item label="(2)">
        <item label="a">some text</item>
        <item label="b">some text</item>
        <anotherNode>some text</anotherNode>
        <item label="c">some text</item>
        <item label="d">some text</item>
    </item>
</list>

产生了想要的、正确的结果:

<list>
   <item label="(1)">some text</item>
   <item label="(2)">
      <list>
         <item label="a">some text</item>
         <item label="b">some text</item>
      </list>
      <anotherNode>some text</anotherNode>
      <list>
         <item label="c">some text</item>
         <item label="d">some text</item>
      </list>
   </item>
</list>

关于php - 包装一组 XML 节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3652194/

有关php - 包装一组 XML 节点的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  3. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  4. ruby-on-rails - 如何在 Rails 3 中禁用 XML 解析 - 2

    我想禁用HTTP参数的自动XML解析。但我发现命令仅适用于Rails2.x,它们都不适用于3.0:config.action_controller.param_parsers.deleteMime::XML(application.rb)ActionController::Base.param_parsers.deleteMime::XMLRails3.0中的等价物是什么? 最佳答案 根据CVE-2013-0156的最新安全公告你可以将它用于Rails3.0。3.1和3.2ActionDispatch::ParamsParser::

  5. ruby - 如何使用 Nokogiri::XML::Builder 生成动态标签? - 2

    我正在遍历数组中的一组标签名称,我想使用构建器打印每个标签名称,而不是求助于“我认为:builder=Nokogiri::XML::Builder.newdo|xml|fortagintagsxml.tag!tag,somevalendend会这样做,但它只是创建名称为“tag”的标签,并将标签变量作为元素的文本值。有人可以帮忙吗?这个看起来应该比较简单,我刚刚在搜索引擎上找不到答案。我可能没有以正确的方式提问。 最佳答案 尝试以下操作。如果我没记错的话,我添加了一个根节点,因为Nokogiri需要一个。builder=Nokogi

  6. ruby - 如何让 Nokogiri 解析并返回 XML 文档? - 2

    这是一些奇怪的例子:#!/usr/bin/rubyrequire'rubygems'require'open-uri'require'nokogiri'print"withoutread:",Nokogiri(open('http://weblog.rubyonrails.org/')).class,"\n"print"withread:",Nokogiri(open('http://weblog.rubyonrails.org/').read).class,"\n"运行此返回:withoutread:Nokogiri::XML::Documentwithread:Nokogiri::

  7. 区块链入门教程(6)--WeBASE-Front节点前置服务安装 - 2

    文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定

  8. ruby - 选择包含子节点内文本的父节点 - 2

    基本上我想选择一个节点(div),其中它的子节点(h1,b,h3)包含指定的文本。Childtext1Childtext2...Childtext3我期待的是/html/div/而不是/html/div/h1我在下面有这个,但不幸的是返回了child,而不是div的xpath。expression="//div[contains(text(),'Childtext1')]"doc.xpath(expression)我期待的是/html/div/而不是/html/div/h1那么有没有一种方法可以简单地使用xpath语法来做到这一点? 最佳答案

  9. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  10. ruby - 模式加载时出现 Nokogiri::XML::Schema SyntaxError - 2

    我正在尝试加载SAML协议(protocol)架构(具体来说:https://www.oasis-open.org/committees/download.php/3407/oasis-sstc-saml-schema-protocol-1.1.xsd),但在执行此操作之后:schema=Nokogiri::XML::Schema(File.read('saml11_schema.xsd'))我得到这个输出:Nokogiri::XML::SyntaxErrorException:Element'{http://www.w3.org/2001/XMLSchema}element',att

随机推荐