使用XSLT从嵌套XML转换为扁平化XML结构

时间:2022-11-10 14:28:06

I am trying this task in XSLT: Convert XML with nested elements to a less nested XML format.

我在XSLT中尝试此任务:使用嵌套元素将XML转换为嵌套较少的XML格式。

Convert from:

<example>
 <value>
  aaa
   <value>
    bbb
      <value>
       ccc
      </value>
   </value>
 </value>
</example>

To:

<example>
  <value>aaa</value>
  <value>aaa</value>
  <value>bbb</value>
  <value>bbb</value>
  <value>ccc</value>
  <value>ccc</value>
</example>

I have been trying find the solution, but I have only this:

我一直在尝试找到解决方案,但我只有这个:

    <xsl:template match="/">
      <exmaple>
         <xsl:apply-templates/>
      </exmaple>
    </xsl:template>

    <xsl:template match="//value/text()">

     <value><xsl:value-of select="."/></value>
     <value><xsl:value-of select="."/></value>

    </xsl:template>

Result (problem with empty tags):

结果(空标签有问题):

<exmaple>
<value>
aaa
</value><value>
aaa
</value><value>
bbb
</value><value>
bbb
</value><value>
ccc
</value><value>
ccc
</value><value>
</value><value>
</value><value>
</value><value>
</value>
</exmaple>

2 个解决方案

#1


1  

Try this template with the XPath //value/text()[1]:

使用XPath // value / text()[1]尝试此模板:

<xsl:template match="//value/text()[1]">
    <value><xsl:value-of select="." /></value>
    <value><xsl:value-of select="." /></value>
</xsl:template>

The trick is that you need to select the first text node from every <value>, since text() will return collection of them.

诀窍是你需要从每个 中选择第一个文本节点,因为text()将返回它们的集合。

#2


2  

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output indent="yes"/>

    <xsl:template match="example">
        <xsl:copy>
            <xsl:apply-templates select=".//value"/>
        </xsl:copy>
    </xsl:template>

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

</xsl:stylesheet>

#1


1  

Try this template with the XPath //value/text()[1]:

使用XPath // value / text()[1]尝试此模板:

<xsl:template match="//value/text()[1]">
    <value><xsl:value-of select="." /></value>
    <value><xsl:value-of select="." /></value>
</xsl:template>

The trick is that you need to select the first text node from every <value>, since text() will return collection of them.

诀窍是你需要从每个 中选择第一个文本节点,因为text()将返回它们的集合。

#2


2  

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output indent="yes"/>

    <xsl:template match="example">
        <xsl:copy>
            <xsl:apply-templates select=".//value"/>
        </xsl:copy>
    </xsl:template>

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

</xsl:stylesheet>