Сложный XML-запрос XSLT, как соединения SQL - PullRequest
1 голос
/ 19 июля 2011

У нас есть XML-файл в формате, показанном ниже.

<toploop id="iamroot">
    <firstinner>
        <inner1 Sequence="001">
          <Number>321</Number>
        </inner1>
        <inner1 Sequence="002">
          <Number>345</Number>
        </inner1>
    </firstinner>
    <secondinner>
        <inner2 Sequence="001">
          <Number>321</Number>
          <secondNumber>189</secondNumber>
        </inner2>
        <inner2 Sequence="002">
          <Number>345</Number>
          <secondNumber>998</secondNumber>
        </inner2>
    </secondinner>
</toploop>

Я много чего перепробовал, но, будучи новичком в XSLT / XPath, я не могу получить запрос для представления данныхкак показано ниже.

iamroot,001,321,189
iamroot,002,345,998

Как вы можете заметить, я хочу проверить, соответствует ли последовательность inner1 тега firstinner, число совпадает с последовательностью inner2 тега secondinner, число, а затем потянуть значение тега secondNumber тега inner2 второго идентификатора вдоль стороны этих,Точно так же как внутреннее объединение двух таблиц в SQL.Можем ли мы сделать это в XSLT?Я пытался сопоставить значения, но я не знаю, как сопоставить данные в одном и том же XML-файле.Пожалуйста помоги.Заранее спасибо.Я использую Xalan-C для того же.

Обновление: Спасибо Кей и LarsH.Я попробовал следующий сценарий.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output  method="text" />
<xsl:template match="inner2" />   
<xsl:template match="inner1">
<xsl:variable name="inner2" select="../../secondinner/inner2[Number = current()/Number and @Sequence = current()/@Sequence]"/>   
<xsl:if test="$inner2">     
<xsl:value-of select="concat(/toploop/@id, ',', /toploop/firstinner/inner1/@Sequence, ',', /toploop/firstinner/inner1/Number, ',', $inner2/secondNumber, ',')" />
</xsl:if> 
</xsl:template> 
</xsl:stylesheet>

Он выдает вывод, как показано ниже.

    iamroot,001,321,189,
    iamroot,002,345,998,

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

iamroot, 001,321,189,

iamroot, 002,345,998,

Еще раз спасибо.

Ответы [ 2 ]

4 голосов
/ 19 июля 2011

Примерно так:

<xsl:template match="inner1">
  <xsl:variable name="inner2" 
   select="../../secondinner/inner2[Number = current()/Number 
                                    and @Sequence = current()/@Sequence"/>
  <xsl:if test="$inner2">
    <xsl:value-of select="concat(../../@id, ',', @Sequence, ',', 
                          Number, ',', $inner2/secondNumber"/>
  </xsl:if>
</xsl:template>

Здесь вы делаете соединение двух вещей: . привязано к одному из них и current() к другому.

Для более общего решения, которое позволяет объединять три или более наборов узлов, вы можете связать явные переменные, например, <xsl:variable name="one" select="."/>.

1 голос
/ 19 июля 2011

Помимо исправления опечатки, где @inner2 должно быть $inner2 ...

Вам также необходимо добавить шаблон для «проглатывания» элементов, которые вы не хотите обрабатывать.Прямо сейчас шаблон по умолчанию копирует строковое содержимое всех элементов, кроме inner1, в вывод.Таким образом, вам необходимо переопределить этот шаблон по умолчанию, по крайней мере для элементов inner2:

<xsl:template match="inner2" />

Тот факт, что этот шаблон пуст, означает, что элементы <inner2> будут использованы без вывода чего-либо и без обработки их потомков.

...