Java 如何使用xslt将列表类型的元素的xml重新构造为元素

Java 如何使用xslt将列表类型的元素的xml重新构造为元素,java,xml,xslt,Java,Xml,Xslt,我有一个从JSON到XML转换生成的XML,格式如下 完整的原始XML示例: 例1: <?xml version="1.0" encoding="UTF-8"?> <linked-hash-map> <entry> <string>dataset</string> <linked-hash-map> <entry> <string>

我有一个从JSON到XML转换生成的XML,格式如下

完整的原始XML示例:

例1:

<?xml version="1.0" encoding="UTF-8"?>
<linked-hash-map>
   <entry>
      <string>dataset</string>
      <linked-hash-map>
         <entry>
            <string>id</string>
            <string>120140</string>
         </entry>
         <entry>
            <string>dataset_code</string>
            <string>GDP</string>
         </entry>
         <entry>
            <string>column_names</string>
            <list>
               <string>DATE</string>
               <string>VALUE</string>
            </list>
         </entry>
         <entry>
            <string>frequency</string>
            <string>quarterly</string>
         </entry>
         <entry>
            <string>type</string>
            <string>Time Series</string>
         </entry>
         <entry>
            <string>premium</string>
            <boolean>false</boolean>
         </entry>
         <entry>
            <string>data</string>
            <list>
               <list>
                  <string>2016-07-01</string>
                  <double>18675.3</double>
               </list>
               <list>
                  <string>2016-04-01</string>
                  <double>18450.1</double>
               </list>
               <list>
                  <string>2016-01-01</string>
                  <double>18281.6</double>
               </list>
            </list>
         </entry>
         <entry>
            <string>database_id</string>
            <int>118</int>
         </entry>
      </linked-hash-map>
   </entry>
</linked-hash-map>

数据集
身份证件
120140
数据集\u代码
国内生产总值
列名
日期
价值
频率
每季的
类型
时间序列
溢价
假的
数据
2016-07-01
18675.3
2016-04-01
18450.1
2016-01-01
18281.6
数据库标识
118
例2:

<?xml version="1.0" encoding="UTF-8"?>
<linked-hash-map>
   <entry>
      <string>dataset</string>
      <linked-hash-map>
         <entry>
            <string>dataset_code</string>
            <string>AAPL</string>
         </entry>
         <entry>
            <string>column_names</string>
            <list>
               <string>DATE</string>
               <string>Open</string>
               <string>High</string>
               <string>Low</string>
               <string>Close</string>
            </list>
         </entry>
         <entry>
            <string>frequency</string>
            <string>quarterly</string>
         </entry>
         <entry>
            <string>type</string>
            <string>Time Series</string>
         </entry>
         <entry>
            <string>data</string>
            <list>
               <list>
                  <string>2016-07-01</string>
                  <double>116.45</double>
                  <double>117.1095</double>
                  <double>116.4</double>
                  <double>116.73</double>
               </list>
               <list>
                  <string>2016-04-01</string>
                  <double>18450.1</double>
                  <double>113.1095</double>
                  <double>112.4</double>
                  <double>100.73</double>
               </list>
               <list>
                  <string>2016-01-01</string>
                  <double>18281.6</double>
                  <double>157.1095</double>
                  <double>136.4</double>
                  <double>156.73</double>
               </list>
            </list>
         </entry>
         <entry>
            <string>database_id</string>
            <int>218</int>
         </entry>
      </linked-hash-map>
   </entry>
</linked-hash-map>

数据集
数据集\u代码
AAPL
列名
日期
打开
高
低
接近
频率
每季的
类型
时间序列
数据
2016-07-01
116.45
117.1095
116.4
116.73
2016-04-01
18450.1
113.1095
112.4
100.73
2016-01-01
18281.6
157.1095
136.4
156.73
数据库标识
218
以下部分需要在两个XML中进行转换

<entry>
       <string>column_names</string>
        <list>
          <string>DATE</string>
          <string>VALUE</string>
        </list>
</entry>
     <entry>
            <string>data</string>
            <list>
              <list>
                <string>2016-07-01</string>
                <double>18675.3</double>
              </list>
              <list>
                <string>2016-04-01</string>
                <double>18450.1</double>
              </list>
             </list>
    </entry>

列名
日期
价值
数据
2016-07-01
18675.3
2016-04-01
18450.1
如何将其转换为以下格式

一,


2016-07-01
18675.3
2016-04-01
18450.1
二,


2016-07-01
18675.3
2016-04-01
18450.1
注:此处所有数据(日期、值、数据、条目等)都是动态的

正在寻找XSLT的通用实现以获得所需的输出。如果xslt不可能,那么我想用Java来转换它


任何帮助都将不胜感激。`

以下样式表将适用于您的两个示例。我不认为它需要比这更通用——如果是这样的话,我不知道该怎么做

XSLT1.0

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

<xsl:template match="/linked-hash-map">
    <xsl:variable name="col-names" select="entry/linked-hash-map/entry[string='column_names']/list/string" />
    <root>
        <xsl:for-each select="entry/linked-hash-map/entry[string='data']/list/list">
            <xsl:variable name="current-row" select="." />
            <entry>
                <xsl:for-each select="$col-names">
                    <xsl:variable name="i" select="position()" />
                    <xsl:element name="{.}">
                        <xsl:value-of select="$current-row/*[$i]" />
                    </xsl:element>
                </xsl:for-each>
            </entry>
        </xsl:for-each>
    </root>
</xsl:template>

</xsl:stylesheet>


与之一样,这假设提供的列名是有效的XML元素名。

Hmmm,您能否详细说明一下:这里的所有数据(日期、值、数据、条目等)都是动态的。你能描述一下转换的规则吗。例如:“始终跳过第一个XML元素…”1。您显示的输入不是格式良好的XML(没有单个根元素)2.很难相信所有元素名称都是“动态的”。无论如何,我们需要一些规则。嗨,Stefan,谢谢你调查这件事。抱歉搞混了。列名(“日期”、“值”)是动态的。因为我们不确定列表中会出现多少列,以及文本是什么。另外,下一个数组“data”名称也不是静态的。这可能是数据集或其他东西。据我所知,标题(列名列表)和数据包含在两个列表中,我们需要将这两个列表合并到一个数组或平面元素中。并从xml中删除各个列表。因此,当我们生成xsd时,我们可以看到这些列名。嗨,Michael,感谢您的关注。为这一混乱道歉。它将有一个根元素。我已经发布了一些关于上述动态数据的信息。请让我知道如果你需要任何进一步的信息。你能提供另一个样本来显示动态性质吗?通常,像
这样的前几个重复节点有助于构建通用脚本。谢谢Michael。对的上一次你也帮了我。它确实对我有用。你能不能帮我把这两件东西合在一起,并提供最终的样式表。原始示例xml已经发布在这里的主题中。这两个答案是不兼容的,因为这两个输入非常不同:这里有一个列名列表,每行有一个单独的值列表;在这里,您将名称和值作为一对同级节点。您好,Michael,在创建元素时,如何将空格或特殊字符替换为u,如果列的u名称值是这样的。“调整打开”、“拆分比率”?使用
translate()
函数。
<entry>
    <Date>2016-07-01</Date>
    <Value>18675.3</Value>
    <Date>2016-04-01</Date>
    <Value>18450.1</Value>
    </entry>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/linked-hash-map">
    <xsl:variable name="col-names" select="entry/linked-hash-map/entry[string='column_names']/list/string" />
    <root>
        <xsl:for-each select="entry/linked-hash-map/entry[string='data']/list/list">
            <xsl:variable name="current-row" select="." />
            <entry>
                <xsl:for-each select="$col-names">
                    <xsl:variable name="i" select="position()" />
                    <xsl:element name="{.}">
                        <xsl:value-of select="$current-row/*[$i]" />
                    </xsl:element>
                </xsl:for-each>
            </entry>
        </xsl:for-each>
    </root>
</xsl:template>

</xsl:stylesheet>