Не удается получить отладочный вывод правильно, используя XSLT / XPath 2.0 - PullRequest
2 голосов
/ 27 февраля 2012

У меня есть такой XML-код:

<?xml version="1.0" encoding="UTF-8"?>

<Section>
    <Chapter>
        <Cell colname="1">
            <Value>A</Value>
        </Cell>
        <Cell colname="2">
            <MyValue>AAA</MyValue>
            <MyValue>BBB</MyValue>
        </Cell>
        <Cell colname="3">
            <MyCar>Honda</MyCar>
        </Cell>
    </Chapter>
    <Chapter>
        <Cell colname="1">
            <Value>C</Value>
        </Cell>
        <Cell colname="2">
            <MyValue>CCC</MyValue>
        </Cell>
        <Cell colname="3">
            <MyCar>Toyota</MyCar>
        </Cell>
    </Chapter>
</Section>

У меня есть такой XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes"/>

    <xsl:template match="/">
        <xsl:apply-templates select="Section/Chapter"/>
    </xsl:template>

    <xsl:template match="Chapter">
        <xsl:apply-templates select="./Cell/MyValue"/>
    </xsl:template>

    <xsl:template match="MyValue">
        <xsl:message>
            <xsl:value-of select="../../Cell/@colname"/>
            <xsl:value-of select="../../Cell[@colname='1']/Value"/>
            <xsl:value-of select="."/>
            <xsl:value-of select="../../Cell[@colname='3']/MyCar"/>
        </xsl:message>
    </xsl:template>

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

</xsl:stylesheet>

Проблема в том, что отладочный вывод отображается как 1 2 3 A AAA Honda 12 3 A BBB Honda 1 2 3 C CCC Toyota.Я хотел бы получить что-то вроде 1 A 2 AAA 3 Honda 1 A 2 BBB 3 Honda 1 C 2 CCC 3 Toyota.В основном, получение значения атрибута colname правильно.

Итак, несколько вопросов:

  1. Что я сделал не так?
  2. Существует последовательность 1 2 3, сгенерированная почему?.

TIA,

Джон

Ответы [ 2 ]

2 голосов
/ 27 февраля 2012

Итак, несколько вопросов:

  1. Что я сделал не так?

Вы не указали точно необходимые выражения.

* * 1010
  1. Существует последовательность 1 2 3, сгенерированная почему?

Поскольку ../../Cell/@colname выбирает атрибут colname для каждый Cell дочерний элемент прародителя текущего узла Chapter.

Решение

Используйте :

<xsl:template match="MyValue">
    <xsl:message>
        <xsl:value-of select="../../Cell[1]/@colname"/>
        <xsl:value-of select="../../Cell[@colname='1']/Value"/>
        <xsl:value-of select="../@colname"/>
        <xsl:value-of select="."/>
        <xsl:value-of select="../../Cell[3]/@colname"/>
        <xsl:value-of select="../../Cell[@colname='3']/MyCar"/>
    </xsl:message>
</xsl:template>

Вывод отладки - именно то, что нужно :

1A2AAA3Honda
1A2BBB3Honda
1C2CCC3Toyota

Вы также можете использовать небольшую модификацию ответа на свой предыдущий вопрос :

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

     <xsl:template match="Chapter">
      <xsl:apply-templates select="Cell[1]"/>
     </xsl:template>

     <xsl:template match="Cell">
      <xsl:param name="pText" as="xs:string*"/>

      <xsl:apply-templates select="*[1]">
       <xsl:with-param name="pText" select="$pText"/>
      </xsl:apply-templates>
     </xsl:template>

     <xsl:template match="Cell/*">
      <xsl:param name="pText" as="xs:string*"/>

      <xsl:variable name="vText" as="xs:string*"
       select="$pText, ../@colname, string(.)"/>

      <xsl:sequence select=
       "$vText
          [not(current()/../following-sibling::Cell)]"/>
      <xsl:apply-templates select="../following-sibling::Cell[1]">
        <xsl:with-param name="pText" select="$vText"/>
      </xsl:apply-templates>
      <xsl:apply-templates select="following-sibling::*">
        <xsl:with-param name="pText" select="$pText"/>
      </xsl:apply-templates>
     </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к предоставленному документу XML :

<Section>
    <Chapter>
        <Cell colname="1">
            <Value>A</Value>
        </Cell>
        <Cell colname="2">
            <MyValue>AAA</MyValue>
            <MyValue>BBB</MyValue>
        </Cell>
        <Cell colname="3">
            <MyCar>Honda</MyCar>
        </Cell>
    </Chapter>
    <Chapter>
        <Cell colname="1">
            <Value>C</Value>
        </Cell>
        <Cell colname="2">
            <MyValue>CCC</MyValue>
        </Cell>
        <Cell colname="3">
            <MyCar>Toyota</MyCar>
        </Cell>
    </Chapter>
</Section>

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

1 A 2 AAA 3 Honda 1 A 2 BBB 3 Honda 1 C 2 CCC 3 Toyota
0 голосов
/ 27 февраля 2012

Следующий результат дает желаемый результат:

  1. Вы получаете 1 2 3, потому что ../../Cell/@colname соответствует всем трем ячейкам в текущей главе.Вот почему я изменил его на Cell [1]
  2. Я не уверен, насколько «жестко закодированными» должны быть имена столбцов, как, например, при использовании colname 3 для поиска значения colname 3 кажется довольностранный.Вот почему я просто выводил его в виде текста

? Xml version = "1.0" encoding = "UTF-8"?>> 1009 *

<xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes"/>

<xsl:template match="/">
    <xsl:apply-templates select="Section/Chapter"/>
</xsl:template>

<xsl:template match="Chapter">
    <xsl:apply-templates select="./Cell/MyValue"/>
</xsl:template>

<xsl:template match="MyValue">
    <xsl:message>
        <xsl:value-of select="../../Cell[1]/@colname"/>
        <xsl:value-of select="../../Cell[@colname='1']/Value"/>
        <xsl:value-of select="../@colname"/>
        <xsl:value-of select="."/>
        <xsl:text>3</xsl:text>
        <xsl:value-of select="../../Cell[@colname='3']/MyCar"/>
    </xsl:message>
</xsl:template>

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

</xsl:stylesheet>
...