Индексирование XSLT на основе вывода, а не ввода - PullRequest
1 голос
/ 20 декабря 2011

У меня есть некоторый исходный XML, содержащий различные элементы, которые преобразуются таблицей стилей в выходные элементы с тем же именем. Затем для выходных элементов требуется элемент index. Моим первым выбором было использование position (), но, конечно, это работает только для контекста xsl: for-each, в котором они расположены.

Вот пример XML:

<Root>
    <TypeA Val="First Value"/>
    <TypeA Val="Second Value"/>
    <NotToBeTransformed Val="ignoreme"/>
    <TypeB Val="Third Value"/>
    <TypeB Val="Fourth Value"/>
</Root>

И вот как я бы хотел, чтобы он отображался как вывод:

<Output>
    <Destination>
        <Index>1</Index>
        <Content>First Value</Content>
    </Destination>
    <Destination>
        <Index>2</Index>
        <Content>Second Value</Content>
    </Destination>
    <Destination>
        <Index>3</Index>
        <Content>Third Value</Content>
    </Destination>
    <Destination>
        <Index>4</Index>
        <Content>Fourth Value</Content>
    </Destination>
</Output>

Мой простой XSLT выглядит следующим образом:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
    <Output>
        <xsl:for-each select="//TypeA">
            <Destination>
                <Index><xsl:value-of select="position()"/></Index>
                <Content><xsl:value-of select="@Val"/></Content>
            </Destination>
        </xsl:for-each>
        <xsl:for-each select="//TypeB">
            <Destination>
                <Index><xsl:value-of select="position()"/></Index>
                <Content><xsl:value-of select="@Val"/></Content>
            </Destination>
        </xsl:for-each>
    </Output>
</xsl:template>

Но при этом выводится Индекс со значениями 1 и 2 для каждого из наборов исходных элементов. Можно ли это сделать в XSLT или это нужно будет обработать снова? Я делаю преобразование с кодом C #, чтобы я мог запустить начальное преобразование, а затем установить значения индекса в коде.

Любая помощь будет принята с благодарностью!

1 Ответ

2 голосов
/ 20 декабря 2011

Вам вообще не нужно использовать xsl:for-each (старайтесь всегда избегать этого), также нет необходимости обрабатывать TypeA и TypeB элементы отдельно.

Это преобразование:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
  <Output>
   <xsl:apply-templates select="TypeA|TypeB"/>
  </Output>
 </xsl:template>
 <xsl:template match="*/*">
    <Destination>
        <Index><xsl:value-of select="position()"/></Index>
        <Content><xsl:value-of select="@Val"/></Content>
    </Destination>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<Root>
    <TypeA Val="First Value"/>
    <TypeA Val="Second Value"/>
    <NotToBeTransformed Val="ignoreme"/>
    <TypeB Val="Third Value"/>
    <TypeB Val="Fourth Value"/>
</Root>

дает требуемый, правильный результат :

<Output>
   <Destination>
      <Index>1</Index>
      <Content>First Value</Content>
   </Destination>
   <Destination>
      <Index>2</Index>
      <Content>Second Value</Content>
   </Destination>
   <Destination>
      <Index>3</Index>
      <Content>Third Value</Content>
   </Destination>
   <Destination>
      <Index>4</Index>
      <Content>Fourth Value</Content>
   </Destination>
</Output>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...