XSLT 将具有父节点的节点移动到具有给定属性的每个父节点的兄弟节点中

Posted

技术标签:

【中文标题】XSLT 将具有父节点的节点移动到具有给定属性的每个父节点的兄弟节点中【英文标题】:XSLT move node with a parent node into each parent's siblings that have a given attribute 【发布时间】:2016-06-09 16:25:05 【问题描述】:

我有以下来源a.html

<html>
  <head>
    <title>title</title>
  </head>
  <body>
    <div class="a">a
      <div class="a1">a1</div>
      <div class="x" type="typea2">x
        <div class="x1">x1</div>
      </div>
      <div class="a3">a3</div>
    </div>
    <div class="b">b_1
      <div class="b1">b1_1</div>
      <div class="b3">b3_11</div>
      <div class="b3">b3_12</div>
      <div class="b3">b3_13</div>
    </div>
    <div class="b">b_2
      <div class="b1">b1_2</div>
      <div class="b3">b3_21</div>
      <div class="b3">b3_22</div>
    <div class="b">b_3
      <div class="b1">b1_3</div>
      <div class="b3">b3_31</div>
      <div class="b3">b3_32</div>
      <div class="b3">b3_33</div>
      <div class="b3">b3_34</div>
    </div>
  </body>
</html>

我想:

    将元素 div class="x" 复制到每个 div class="b" 中,在其自己的文本和任何 div class="b1" 之后 从 div class="a" 中移除原来的 div class="x"

输出应该是:

<html>
  <head>
    <title>title</title>
  </head>
  <body>
    <div class="a">a
      <div class="a1">a1</div>
      <div class="a3">a3</div>
    </div>
    <div class="b">b_1
      <div class="b1">b1_1</div>
      <div class="x" type="typea2">x
        <div class="x1">x1</div>
      </div>
      <div class="b3">b3_11</div>
      <div class="b3">b3_12</div>
      <div class="b3">b3_13</div>
    </div>
    <div class="b">b_2
      <div class="b1">b1_2</div>
      <div class="x" type="typea2">x
        <div class="x1">x1</div>
      </div>
      <div class="b3">b3_21</div>
      <div class="b3">b3_22</div>
    <div class="b">b_3
      <div class="b1">b1_3</div>
      <div class="x" type="typea2">x
        <div class="x1">x1</div>
      </div>
      <div class="b3">b3_31</div>
      <div class="b3">b3_32</div>
      <div class="b3">b3_33</div>
      <div class="b3">b3_34</div>
    </div>
  </body>
</html>

我使用了以下shell脚本a.sh:

xsltproc --html a.xslt a.html > b.html

使用以下 a.xslt:

<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()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <!-- ignore x-inside-a -->
 <xsl:template match="//div[@class='a']/div[@class='x']"/>

 <!-- place the x-inside-a into each b after text() and b1 -->
 <xsl:template match="div[@class='b']">
  <xsl:copy>
   <xsl:copy-of select="//div[@class='a']/div[@class='x']" />
   <xsl:apply-templates />
  </xsl:copy>
 </xsl:template>

</xsl:stylesheet>

但是我没有得到想要的结果?

我可以请你帮忙吗?

【问题讨论】:

div class="b" 中是否总是有一个div class="b1"?或者如果div class="b1" 不存在,你想在哪里插入另一个div 嗨,马丁。是的,div class="b1" 始终存在于 div class="b" 中。 【参考方案1】:

如果内部div 始终存在,我会为它编写一个模板:

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

 <!-- ignore x-inside-a -->
 <xsl:template match="div[@class='a']/div[@class='x']"/>

 <!-- place the x-inside-a into each b after b1 -->
 <xsl:template match="div[@class='b']/div[@class = 'b1']">
  <xsl:call-template name="identity"/>
  <xsl:copy-of select="//div[@class='a']/div[@class='x']" />
 </xsl:template>

</xsl:stylesheet>

【讨论】:

以上是关于XSLT 将具有父节点的节点移动到具有给定属性的每个父节点的兄弟节点中的主要内容,如果未能解决你的问题,请参考以下文章

将属性和值填充到第4个父节点的XML文件的所有父节点

如何合并具有“相同父亲”、相同方法和相同 id=0 的两个节点(使用 XSLT)?

如何获取具有相同名称的元素并根据 XSLT 中的子节点值对它们进行排序

Python爬虫lxml解析实战

获取父节点 XSLT 的属性

使用 XSLT 将具有相同 ID 的元素 (XML) 合并到 txt 文件