Удаление атрибутов из XSLT и работа с набором результатов - PullRequest
4 голосов
/ 30 июня 2011

Возможно ли удалить атрибуты xml из XSLT И работать с полученным преобразованием?

Другими словами, у меня есть следующий XML:

<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="XML_TEST.xslt"?>
<report xmlns="abc123">
<book>
<page id="22">

</page>
<page id="23">

</page>
</book>
</report>

Я знаю, что могу использовать следующий XSLT для удаления атрибутов:

 <xsl:template match ="@*" >
            <xsl:attribute name ="{local-name()}" >
                <xsl:value-of select ="." />
            </xsl:attribute>
            <xsl:apply-templates/>
        </xsl:template>
        <xsl:template match ="*" >
            <xsl:element name ="{local-name()}" >
                <xsl:apply-templates select ="@* | node()" />
            </xsl:element>
  </xsl:template>

Но если бы я хотел прочитать значения, используя следующий шаблон

<xsl:template match="report">
    <xsl:for-each select="book/page">
        <xsl:value-of select="@id"/>
    </xsl:for-each>
</xsl:template>

Можно ли связать этот шаблон с выходом первых двух?

Заранее спасибо,

-R.

Ответы [ 3 ]

1 голос
/ 30 июня 2011

В этом вопросе есть что-то странное: Я не вижу, как заголовок вашего вопроса соответствует содержанию .

В заголовке вы запрашиваете двухпроходное преобразование, при котором первый проход должен удалить атрибуты , а второй должен работать с ним.

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

Согласно ответу @ Dimitre на содержание вашего вопроса (который, я думаю, не отвечает на реальный вопрос) Я постараюсь ответить на заголовок вашего вопроса, который кажется гораздо более интересным (и отвечающим).


Удаление атрибутов из XSLT ...

Чтобы удалить атрибуты (и получить преобразование без пространств имен), вы можете работать с Identity Transformation .Поскольку вы хотите многоходовую передачу, вы должны скопировать содержимое преобразования в переменную в первом проходе.

Вы можете использовать mode , чтобы адресовать процесс элементам в первом проходе.

... и работать с результатомset

Для работы с набором результатов (формально известный как фрагмент дерева результатов ) необходимо применить шаблоны с помощью ссылка на переменную, определенную в первом проходе .Добро пожаловать!Это второй проход:)

Двухпроходное преобразование относительно доступно в XSLT 2.0 по сравнению с XSLT 1.0 благодаря способности XSLT 2.0 применять шаблоны к RTF.В XSLT 1.0 вам потребуется специальная функция расширения, которая называется node-set().


XSLT 2.0 будет выглядеть следующим образом (чистый пример):

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

    <xsl:output indent="yes" omit-xml-declaration="yes"/>   
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/">
        <xsl:variable name="FirstPass">
            <xsl:copy>
                <xsl:apply-templates select="/" mode="FirstPass"/>
            </xsl:copy>
        </xsl:variable>

        <xsl:apply-templates select="$FirstPass/report/book/page"/>
    </xsl:template>

    <xsl:template match="node()" mode="FirstPass">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select ="node()" mode="FirstPass"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="page">
        <xsl:value-of select="count(@*)"/>
    </xsl:template>

</xsl:stylesheet> 

с результатами (применимо к вашему примеру ввода)

00

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

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

и второй проход :

 <xsl:apply-templates select="exslt:node-set($FirstPass)/report/book/page"/>
1 голос
/ 30 июня 2011

Можно ли удалить атрибуты xml из XSLT и работать с полученным преобразованием?

Да, просто выполните поиск "многопроходного преобразования" , и выВы найдете много ответов с хорошими примерами кода.

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

Просто используйте:

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

 <xsl:template match="x:page">
  <xsl:value-of select="@id"/>
 </xsl:template>
</xsl:stylesheet>

И если пространство имен по умолчанию XML-документа заранее неизвестно, вы все равно можете получить требуемые результаты за один проход :

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

 <xsl:template match="*[name()='page']">
  <xsl:value-of select="@id"/>
 </xsl:template>
</xsl:stylesheet>
0 голосов
/ 30 июня 2011

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

Вы можете выполнить многоступенчатое преобразование в пределах одной таблицы стилей (удерживая результаты в переменных, особенно в XSLT 2.0), или вы можете сделать это, используя несколько таблиц стилей. Вы можете управлять конвейером, включающим несколько таблиц стилей с использованием различных технологий (XProc, Coccoon, Orbeon, Ant, xmlsh) или из своего собственного кода Java / C #. Преимущество использования нескольких таблиц стилей заключается в возможности многократного использования компонентов конвейера.

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