草庐IT

xml - XSLT 合并节点

coder 2024-07-01 原文

所以我有一个凌乱的 xhtml 文件,我想将其转换为 xml。这是一个带有很多“p”标签的词典,我想把它们整理出来。这是 xhtml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta content="2018-06-29T10:12:48Z" name="dcterms.created" />
        <meta content="2018-06-29T10:12:48Z" name="dcterms.modified" />
    </head>
    <body>
        <p><b>Aesthetik</b></p>
        <p>text about aesthetics.</p>
        <p><b>Expl: </b>explanation about aesthetics</p>
        <p><b>BegrG: </b>origin of the term</p>
        <p>more origin of the term</p>
        <p><b>Allegorese</b></p>
        <p>text about Allegorese</p>
        <p><b>Expl: </b>explanation about Allegorese</p>
        <p><b>BegrG: </b>origin of Allegorese</p>
    </body>
</html>

XSLT 文件如下所示(其他标记还有几行,此处未包括在内):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://www.w3.org/1999/xhtml">

<xsl:template match="head"/>

<xsl:template match="text()">
    <xsl:value-of select="normalize-space()"/>
</xsl:template>

<xsl:template match="body">
    <lexica>
        <xsl:apply-templates/>      <!-- create root node lexica -->
    </lexica>
</xsl:template>

<xsl:template match="p">
    <p>
        <xsl:apply-templates/> <!-- copy same tags for better visuality -->
    </p>
</xsl:template>

<xsl:template match="p[b[contains(., 'BegrG')]]">
    <BegrG>
        <xsl:apply-templates/>  <!-- create specific nodes with origin explanation of the word -->
    </BegrG>
</xsl:template>

<xsl:template match="p[b[contains(., 'Expl')]]">
    <Expl>
        <xsl:apply-templates/>  <!-- node with explanation of the word --> 
    </Expl>
</xsl:template>


<xsl:template
    match="
    p[b[not(self::*[contains(., 'Expl')]or
    self::*[contains(., 'BegrG')])]]">  <!-- any other b nodes which are left are lexical items -->
    <Artikel>
        <xsl:apply-templates/>
    </Artikel>
</xsl:template>

最后我的 XML 文件看起来像这样:

    <lexica>
    <Artikel>Aesthetik</Artikel>
    <p>text about aesthetics.</p>
    <Expl>Expl:explanation about aesthetics</Expl>
    <BegrG>BegrG:origin of the term</BegrG>
    <p>more origin of the term</p>
    <Artikel>Allegorese</Artikel>
    <p>text about Allegorese</p>
    <Expl>Expl:explanation about Allegorese</Expl>
    <BegrG>BegrG:origin of Allegorese</BegrG>
</lexica>

它看起来更好但仍然无法工作,因为它的结构不够。例如,术语没有分组,一些“p”标签应该合并到它们之前的兄弟标签中。它应该是这样的:

<lexica>
 <item>
  <Artikel>Aesthetik</Artikel>
  <short>text about aesthetics.</short>
  <Expl>Expl:explanation about aesthetics</Expl>
  <BegrG>BegrG:origin of the term. more origin of the term.</BegrG>
 </item>

 <item>
  <Artikel>Allegorese</Artikel>
  <short>text about Allegorese</short>
  <Expl>Expl:explanation about Allegorese</Expl>
  <BegrG>BegrG:origin of Allegorese</BegrG>
 </item>
</lexica>

我是不是处理错了,或者我应该如何将“p”标签分组到他们有 b- child 的 sibling ?我如何将术语项彼此分开并使其识别何时应该出现关闭标记?

(抱歉我的英语不好)

提前致谢!

最佳答案

XSLT 2/3 具有 for-each-group group-starting-with ( https://www.w3.org/TR/xslt20/#xsl-for-each-group ),因此您可以使用

  <xsl:template match="body">
      <lexica>
          <xsl:for-each-group select="*" group-starting-with="p[b[not(matches(., '^(Expl|BegrG):'))]]">
              <item>
                  <xsl:apply-templates select="current-group()"/>
              </item>
          </xsl:for-each-group>
      </lexica>
  </xsl:template>

我想,例子在 https://xsltfiddle.liberty-development.net/bFDb2CG .

到目前为止,我还不确定是什么决定了将某些 p 元素合并到 BegrG 结果中,也许是嵌套分组 with

  <xsl:template match="body">
      <lexica>
          <xsl:for-each-group select="*" group-starting-with="p[b[not(matches(., '^(Expl|BegrG):'))]]">
              <item>
                  <xsl:for-each-group select="current-group()" group-starting-with="p[b[starts-with(., 'BegrG:')]]">
                      <xsl:choose>
                          <xsl:when test="self::p[b[starts-with(., 'BegrG:')]]">
                              <BegrG>
                                  <xsl:apply-templates select="current-group()/node()"/>
                              </BegrG>
                          </xsl:when>
                          <xsl:otherwise>
                              <xsl:apply-templates select="current-group()"/>
                          </xsl:otherwise>
                      </xsl:choose>
                  </xsl:for-each-group>
              </item>
          </xsl:for-each-group>
      </lexica>
  </xsl:template>

实现:https://xsltfiddle.liberty-development.net/bFDb2CG/1

至于评论中提出的问题,您可以在group-starting-with中添加另一个匹配项:

  <xsl:template match="body">
      <lexica>
          <xsl:for-each-group select="*" group-starting-with="p[b[not(matches(., '^(Expl|BegrG):'))]]">
              <item>
                  <xsl:for-each-group select="current-group()" group-starting-with="p[b[starts-with(., 'Expl:')]] | p[b[starts-with(., 'BegrG:')]]">
                      <xsl:choose>
                        <xsl:when test="self::p[b[starts-with(., 'Expl:')]]">
                              <Expl>
                                  <xsl:apply-templates select="current-group()/node()"/>
                              </Expl>
                          </xsl:when>
                          <xsl:when test="self::p[b[starts-with(., 'BegrG:')]]">
                              <BegrG>
                                  <xsl:apply-templates select="current-group()/node()"/>
                              </BegrG>
                          </xsl:when>
                          <xsl:otherwise>
                              <xsl:apply-templates select="current-group()"/>
                          </xsl:otherwise>
                      </xsl:choose>
                  </xsl:for-each-group>
              </item>
          </xsl:for-each-group>
      </lexica>
  </xsl:template>

https://xsltfiddle.liberty-development.net/bFDb2CG/2

关于xml - XSLT 合并节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52246768/

有关xml - XSLT 合并节点的更多相关文章

  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 - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  3. git使用常见问题(提交代码,合并冲突) - 2

    文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g

  4. Ruby 哈希直接访问与合并 - 2

    有什么区别:@attr[:field]=new_value和@attr.merge(:field=>new_value) 最佳答案 如果您使用的是merge!而不是merge,则没有区别。唯一的区别是您可以在合并参数中使用多个字段(意思是:另一个散列)。例子:h1={"a"=>100,"b"=>200}h2={"b"=>254,"c"=>300}h3=h1.merge(h2)putsh1#=>{"a"=>100,"b"=>200}putsh3#=>{"a"=>100,"b"=>254,"c"=>300}h1.merge!(h2)pu

  5. ruby - 在两个 ActiveRecord 类之间合并/复制属性的好方法? - 2

    之前有人问过这个问题,我发现了以下clip关于如何一次设置一个类对象的所有属性,但由于批量分配保护,这在Rails中是不可能的。(例如,您不能Object.attributes={})有没有一种很好的方法可以将一个类的属性合并到另一个类中?object1.attributes=object2.attributes.inject({}){|h,(k,v)|h[k]=vifObjectModel.column_names.include?(k);h}谢谢。 最佳答案 利用assign_attributes使用:without_prote

  6. ruby - 合并 nanoc 中的项目 - 2

    我一直在尝试使用nanoc用于生成静态网站。我需要组织一个复杂的排列页面,我想让我的内容保持干燥。包含或合并的概念在nanoc系统中如何运作?我已阅读文档,但似乎找不到我想要的内容。例如:我如何获取两个部分内容项并将它们合并到一个新的内容项中。在staticmatic您可以在您的页面中执行以下操作。=partial('partials/shared/navigation')类似的约定在nanoc中如何运作? 最佳答案 这里是nanoc的作者。在nanoc中,部分是布局。因此,您可以拥有layouts/partials/shared/

  7. 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::

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

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

  9. 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::

  10. 区块链入门教程(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生态建设,一定

随机推荐