Xslt 要转换包含混合内容的XML吗

Xslt 要转换包含混合内容的XML吗,xslt,xslt-2.0,Xslt,Xslt 2.0,我的XML如下所示,我想使用XSLT2.0将其转换为前面提到的预期XML格式child1和child2只是示例,在实际的XML中,可以有几个名称不同的节点。我是XSL的初学者 <?xml version="1.0" encoding="utf-8" ?> <properties xmlns="http://www.sss.org"> My Parent level text 1 <b> i am bold</b> not bold <chil

我的XML如下所示,我想使用XSLT2.0将其转换为前面提到的预期XML格式
child1
child2
只是示例,在实际的XML中,可以有几个名称不同的节点。我是XSL的初学者

<?xml version="1.0" encoding="utf-8" ?>
<properties xmlns="http://www.sss.org">
My Parent level text 1 <b> i am bold</b> not bold
<child1>
text1 of first child
<child1val attribute1="testval">36-37</child1val>
text2 of child <sub> subscript</sub>
</child1>    
<child2>
text1 of first child2
<child2val attribute1="testval">444</child2val>
<child2val>555</child2val>
text2 of child2
</child2>
My Parent level text3 in  <b> i am bold</b>
</properties>

我的父级文本1我粗体而非粗体
第一个孩子的文本1
36-37
子下标的text2
第一个孩子的文本1 2
444
555
孩子的文本2
我的父级文本3在“我是粗体的”
预期结果:

<properties xmlns="http://www.sss.org">
<text>
 My Parent level text 1 <b> i am bold</b> not bold
</text>
<child1>
<text> text1 of first child </text>
<child1val attribute1="testval">36-37</child1val>
<text> text2 of child <i> i m italic</i></text>
</child1>    
<child2>
<text> text1 of second child2</text>
<child2val attribute1="testval">444</child2val>
<child2val>555</child2val>
<text> text2 of child2</text>
</child2>
My Parent level text3 in  <b> i am bold</b>

我的父级文本1我粗体而非粗体
第一个孩子的文本1
36-37
孩子的文本2我是斜体的
第二个孩子的文本1
444
555
孩子的文本2
我的父级文本3在“我是粗体的”

缩进XML的方式无助于询问问题的方式。例如,考虑XML的这个缩写样本。

<properties>
My Parent level text 1 <b> i am bold</b> not bold
<child1>
text1 of first child
</child1>    
</properties>

我的父级文本1我粗体而非粗体
第一个孩子的文本1
它的布局方式似乎暗示属性元素有两个子元素。但它没有,它有四个孩子。更清晰的缩进是这样的

<properties>
   My Parent level text 1 
   <b> i am bold</b> 
   not bold
   <child1>
      text1 of first child
   </child1>    
</properties>
<xsl:for-each-group select="node()" 
                    group-adjacent="boolean(self::b|self::i|self::sub|self::text())">

我的父级文本1
我很大胆
不大胆
第一个孩子的文本1
看起来text元素只需要围绕前三个子元素,而不是child1元素。不清楚为什么btext元素中被包围,但是child1没有,但我猜这是因为bI(和sub?)是“html”元素,而child1不是

根据这个假设,您可能可以使用XSLT2.0中的xsl:for each group命令及其group-nexting属性来解决这个问题。如果相邻节点是文本节点,或bisub,则将它们分组,因此命令如下所示

<properties>
   My Parent level text 1 
   <b> i am bold</b> 
   not bold
   <child1>
      text1 of first child
   </child1>    
</properties>
<xsl:for-each-group select="node()" 
                    group-adjacent="boolean(self::b|self::i|self::sub|self::text())">

在此范围内,您可以检查current-grouping-key()函数,以确定是否需要使用text元素包围组

    <xsl:choose>
       <xsl:when test="current-grouping-key()">
          <text>
            <xsl:apply-templates select="current-group()" />
          </text>
       </xsl:when>
       <xsl:otherwise>
            <xsl:apply-templates select="current-group()" />
       </xsl:otherwise>
    </xsl:choose> 

这段代码本身可能只需要为具有其他元素作为子元素的元素运行,而不需要为仅具有单个文本节点作为子元素的元素运行。这意味着它将存在于具有此匹配项的模板中

<xsl:template match="*[*]">

其他节点将使用XSLT进行匹配和复制

试试这个XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.sss.org" xmlns="http://www.sss.org">

  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:template match="*[*]">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:for-each-group select="node()" group-adjacent="boolean(self::b|self::i|self::sub|self::text())">
        <xsl:choose>
           <xsl:when test="current-grouping-key()">
              <text>
                <xsl:apply-templates select="current-group()" />
              </text>
           </xsl:when>
           <xsl:otherwise>
                <xsl:apply-templates select="current-group()" />
           </xsl:otherwise>
        </xsl:choose> 
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

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

(注意这里使用的名称空间,因为XML中的所有元素都在名称空间中)

这将输出以下内容

<properties xmlns="http://www.sss.org">
   <text>
      My Parent level text 1 <b> i am bold</b> not bold
   </text>
   <child1>
      <text>
        text1 of first child
      </text>
      <child1val attribute1="testval">36-37</child1val>
      <text>
         text2 of child <sub> subscript</sub>
      </text>
   </child1>
   <child2>
      <text>
        text1 of first child2
      </text>
      <child2val attribute1="testval">444</child2val>
      <child2val>555</child2val>
      <text>
         text2 of child2
      </text>
   </child2>
   <text>
      My Parent level text3 in  <b> i am bold</b>
   </text>
</properties>

我的父级文本1我粗体而非粗体
第一个孩子的文本1
36-37
子下标的text2
第一个孩子的文本1 2
444
555
孩子的文本2
我的父级文本3在“我是粗体的”