Переместите подузлы в родительские атрибуты с помощью XSLT - PullRequest
3 голосов
/ 18 мая 2009

У меня есть некоторый XML, который содержит записи и вложенные записи, например:

<data>
    <record jsxid="id0x0b60fec0" ID="12429070" Created="2008-10-21T03:00:00.0000000-07:00">
        <record jsxid="id0x0b60ff10" string="101"/>
        <record jsxid="id0x0e64d8e8" string="63"/>
        <record jsxid="id0x2fd83f08" string="Y"/>
    </record>
    <record jsxid="id0x0b60fec0" ID="12429070" Created="2008-10-21T03:00:00.0000000-07:00">
        <record jsxid="id0x0b60ff10" string="102"/>
        <record jsxid="id0x0e64d8e8" string="77"/>
        <record jsxid="id0x2fd83f08" string="Y"/>
    </record>       
<data>

Мне нужно преобразовать его так, чтобы строковый атрибут вложенных записей выводился в родительскую запись как последовательно пронумерованные атрибуты, а затем отбрасывался, например:

<data>
    <record jsxid="id0x0b60fec0" ID="12429070" Created="2008-10-21T03:00:00.0000000-07:00" 1="101" 2="63" 3="Y"/>
    <record jsxid="id0x0b60fec0" ID="12429070" Created="2008-10-21T03:00:00.0000000-07:00" 1="102" 2="77" 3="Y"/>
<data>

Количество вложенных записей в документах произвольно, но в одном и том же документе оно остается статическим.

Будет ли кто-то так любезен, чтобы указать путь к решению XSLT? Большое спасибо.

Ответы [ 2 ]

5 голосов
/ 18 мая 2009

Вот полное решение:

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

  <!-- By default, recursively copy all nodes unchanged -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- But don't process any children of <record> (such as whitespace)... -->
  <xsl:template match="record/node()"/>

  <!-- ...except for doubly-nested records;
       convert them to attributes, named according to position -->
  <xsl:template match="record/record" priority="1">
    <xsl:variable name="pos">
      <xsl:number/>
    </xsl:variable>
    <xsl:attribute name="r{$pos}">
      <xsl:value-of select="@string"/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

Обратите внимание, что я изменил имя ваших атрибутов на "r1", "r2" и т. Д., Поскольку XML не позволяет начинать имя с цифры.

1 голос
/ 18 мая 2009

Это может сделать это, запустите следующий фрагмент XSLT при обработке элементов верхнего уровня <record>:

<xsl:for-each select="record">
    <xsl:attribute name="{position()}">
        <xsl:value-of select="@string" />
    </xsl:attribute>
</xsl:for-each>

По существу, это повторяется для каждого подэлемента <record> и создает элемент <xsl:attribute>, описывающий требуемый атрибут. Функция position() вызывается для получения относительной позиции в элементе верхнего уровня: 1, 2, 3 и т. Д.

Это не полное решение; предполагается некоторое знакомство с XSLT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...