Как наследование XML обычно обрабатывается в XSLT? - PullRequest
0 голосов
/ 07 июля 2011

У меня есть файл XML, который во многих местах использует атрибут base для наследования от типов данных в нескольких документах.Я хочу обработать документ, используя XSLT, как будто он обрабатывает документ со всем наследуемым.Я не видел очевидного способа сделать это, хотя мои знания XSLT довольно минимальны.

Когда я говорю о наследовании, я имею в виду базовый атрибут XML, который позволяет типу данных наследоваться от другого типа данных.Например;

<parameter name="DeviceLog" access="readOnly">
    <description>Vendor-specific log(s).</description>
</parameter>
<parameter base="DeviceLog" access="readOnly" activeNotify="canDeny">
</parameter>

Тег описания здесь должен наследоваться вторым параметром.Поэтому, когда мой XSLT-скрипт обрабатывает второй параметр, он будет читать его как

<parameter name="DeviceLog" access="readOnly" activeNotify="canDeny">
    <description>Vendor-specific log(s).</description>
</parameter>

, может быть, это невозможно сделать?

РЕДАКТИРОВАТЬ: Наследование, о котором я говорило не стандартно.Это было что-то, что было создано тем, кто создал XML-файл, над которым я работал.Мне пришлось написать собственное решение, чтобы объединить все «унаследованные» элементы и атрибуты.

1 Ответ

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

XSLT принимает XML-документ в качестве дерева ввода и затем генерирует вывод.Когда вывод также является XML, он эффективно преобразует дерево ввода в дерево вывода.Это означает, что вам не остается места для изменения дерева ввода во время чтения.Насколько я знаю, вы также не можете передавать частичные результаты в качестве входных данных для шаблонов.Поэтому я предлагаю выполнить два преобразования XSLT подряд.Один для преобразования ввода в желаемый виртуальный промежуточный результат, другой для выполнения фактической обработки, которая потребуется для этого формата, когда унаследованные структуры свернуты в плоские.

XSLT для этого первого шага может использовать этов качестве основы:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="node()|@*">
        <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
    </xsl:template>
    <xsl:template match="//*[@base]">
        <xsl:variable name="base" select="@base"/>
        <xsl:copy><xsl:copy-of select="./node() | ./@*[local-name() != 'base'] | //*[@name=$base]/@*"></xsl:copy-of><xsl:copy-of select="//*[@name=$base]/node()"/></xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Это преобразовало бы следующее ...

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <test name="one" hello="kitty">
        <one hello="world">test</one>
        <two/>
    </test>
    <bogus att="none">
        <test/>
    </bogus>
    <test base="one" run="true" hello="kitty">
        <three/>
    </test>
</root>

... в это:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <test name="one" hello="kitty">
        <one hello="world">test</one>
        <two/>
    </test>
    <bogus att="none">
        <test/>
    </bogus>
    <test name="one" run="true" hello="kitty">
        <three/>
        <one hello="world">test</one>
        <two/>
    </test>
</root>

Есть некоторые крайние случаи дляразрабатывать.Если и элемент с атрибутом name, и элемент с атрибутом base имеют атрибуты с одинаковым именем, процессор обнаружит это и сохранит только один.Это случай с hello="kitty" здесь.Но если эти атрибуты имеют разные значения, результат трудно предсказать.Вы также можете подавить начальный элемент подшипника name.Для этого просто добавьте шаблон, который ничего не выводит для элементов с атрибутом name.

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

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