重新排列XML节点XSL-T / variable?

时间:2015-09-01 17:32:23

标签: xml xslt

我尝试使用以下结构重新排列XML数据:

<Root>
  <List_X>
    <Value>1</Value>
     ...
  </List_X>
  <List_Y>
    <Value>1</Value>
     ...
  </List_Y>
</Root>

类似于:

<Root>
  <List>
    <Value>
      <X>1</X>
      <Y>1</Y>
    </Value>
    ...
  </List_Y>
</Root>

我的尝试是这样的

<for-each select="List_X/*">
  <variable name="pos" select="position()">
  <Value>
    <Test>
      <value-of select="$pos"/>
    </Test>
    <X>
      <value-of select="."/>
    </X>
    <y>
      <value-of select="../../List_Y/Value[$pos]/."/>
    </y>
  </Value>
</for-each>

只有在我停止更改的部分使用pos时才会出现问题(在测试中),有时系统只选择所有的Value节点。

如果我设置一个固定值而不是$ pos(或一个变量eit一个固定值),就可以了。

Ps:数据结构是从Qt QObject(来自propertys usen SimpleXmlModdel ecpossing teo list proppertys)生成的。 Qt Quick XmlTableModell需要更改的元素。

编辑:代码:

:/ xm.xml

<Root>
<List_X>
    <Value>1</Value>
    <Value>2</Value>
    <Value>3</Value>
    <Value>4</Value>
</List_X>
<List_Y>
    <Value>0.1</Value>
    <Value>0.2</Value>
    <Value>0.3</Value>
    <Value>0.4</Value>
</List_Y>

:/ xsl.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<ROOT>
<xsl:for-each select="Root/List_X/*">
<Value>
<xsl:variable name="pos" select="./position()"/>
<Test>
<xsl:value-of select="$pos"/>
</Test>
<X>
<xsl:value-of select="."/>
</X>
<Y>
<xsl:value-of select="../../List_Y/*[$pos]"/>
</Y>
</Value>
</xsl:for-each>
</ROOT>
</xsl:template>
</xsl:stylesheet>

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QBuffer>
#include <QFile>
#include <QStandardItemModel>
#include <QXmlFormatter>
#include <QXmlQuery>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QByteArray xml,xsl,out;

    {
        QFile f(":/xm.xml");
        f.open(QIODevice::ReadOnly);
        xml = f.readAll();
    }
    ui->textEdit->setText(xml);
    {
        QFile f(":/xsl.xsl");
        f.open(QIODevice::ReadOnly);
        xsl = f.readAll();
    }
    ui->textEdit_2->setText(xsl);


    QXmlQuery query(QXmlQuery::XSLT20);
    query.setFocus(xml);
    query.setQuery(xsl);
    QBuffer b(&out);
    b.open(QIODevice::WriteOnly);
    QXmlFormatter serializer(query, &b);
    query.evaluateTo(&serializer);

    ui->textEdit_3->setText(out);
}

MainWindow::~MainWindow()
{
    delete ui;
}

1 个答案:

答案 0 :(得分:0)

以下更改的xsl代码按我的意愿执行。 (更好的解决方案总是很好)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template name="tmplate">
<Value>
<xsl:variable name="posi" select="position()"/>
<Test>
<xsl:value-of select="$posi"/>
</Test>
<X>
<xsl:value-of select="."/>
</X>
<Y>
<xsl:value-of select="../../List_Y/Value[$posi]"/>
</Y>
</Value>
</xsl:template>

<xsl:template match="/">
<ROOT>
<xsl:for-each select="Root/List_X/Value">
<xsl:call-template name="tmplate"/>
</xsl:for-each>
</ROOT>
</xsl:template>
</xsl:stylesheet>

输出:

<ROOT>
    <Value>
        <Test>1</Test>
        <X>1</X>
        <Y>0.1</Y>
    </Value>
    <Value>
        <Test>2</Test>
        <X>2</X>
        <Y>0.2</Y>
    </Value>
    <Value>
        <Test>3</Test>
        <X>3</X>
        <Y>0.3</Y>
    </Value>
    <Value>
        <Test>4</Test>
        <X>4</X>
        <Y>0.4</Y>
    </Value>
</ROOT>

然后可以在Qt XmlTableModell中使用,其中X和Y用于列。