Преобразовать XML из старой схемы в новую схему?

#xml #xslt #xsd #xslt-tools

#xml #xslt #xsd #xslt-tools

Вопрос:

Мне нужно преобразовать XML-документ, который не использует никакой схемы, в другой формат, который использует четко определенную схему.

Итак, в основном я должен преобразовать это:

 <healthCareFacilityTypeCode 
     displayName="Home" 
     codingScheme="Connect-a-thon healthcareFacilityTypeCodes"
    >Home</healthCareFacilityTypeCode>
  

В это:

 <healthCareFacilityTypeCode>
    <code>Home</code>
    <displayName>
        <LocalizedString value="Home" />
    </displayName>
    <schemeName>Connect-a-thon healthcareFacilityTypeCodes</schemeName>
</healthCareFacilityTypeCode>
  

Я знаю, как преобразовать его вручную, посмотрев на схему. Вот фрагмент XSD:

 <xsd:complexType name="DocumentEntryType">
    <xsd:sequence>
        <xsd:element minOccurs="0" 
                     name="healthCareFacilityTypeCode" 
                     type="tns:CodedMetadataType"/>
    </xsd:sequence>
    <xsd:attribute default="false" 
                   name="existing" 
                   type="xsd:boolean" 
                   use="optional"/>
</xsd:complexType>
<xsd:element name="DocumentEntry" type="tns:DocumentEntryType"/>
  

Чего я не знаю, как решить, так это: как использовать целевой XSD для преобразования узла из исходного XML в целевой XML-документ. Я чувствую, что вся информация для выполнения преобразования находится в XSD, но могу ли я ее использовать? как?

Любая помощь будет высоко оценена!

Комментарии:

1. Целевой XSD поможет вам проверить результат преобразования, но напрямую не поможет произвести преобразование. Однако хорошая среда разработки XSLT IDE, такая как Oxygen и, возможно, StylusStudio, поможет вам в значительной степени проверять ваши выходные элементы при разработке таблицы стилей . Кроме того, процессор XSLT 2.0, поддерживающий схему, может проверять свои выходные данные во время выполнения, учитывая схему для результирующего документа.

2. @LarsH IDE XSLT могли бы пойти на один шаг дальше и использовать XSD для обеспечения автоматического завершения для элементов/ атрибутов literal-result, где они разрешены в XSLT. Основная проблема заключается в том, что, если все элементы и атрибуты не объявлены на верхнем уровне XSD (глобально), существует потенциальная двусмысленность при недостаточном контексте. Кроме того, это не может помочь там, где инструкции xsl: element и xsl:attribute используются вместо эквивалентов буквального результата, но я думаю, что это лучше, чем ничего.

3. @pgfearo — Я думаю, что IDE действительно обеспечивают ускоренное завершение, как вы описали, но я не часто использую XSD, поэтому я не уверен. Как вы говорите, это все еще не полное решение, но может быть полезным.

4. @LarsH Ну, некоторые предоставляют список всех возможных элементов, но они не уточняют этот список в соответствии с контекстом или не выделяют элементы буквального результата с помощью конструкторов последовательности для содержимого, которое, как известно (со статическим контекстом), является недопустимым, т. Е. есть возможности для улучшения

Ответ №1:

Последовал предложениям, и вот что я придумал. Не идеально, но этого достаточно для моей цели.

     <xsl:template match="XDSDocumentEntry">
        <DocumentEntryType>
            <xsl:call-template name="namespaceChange"/>
            <xsl:apply-templates/>
        </DocumentEntryType>
    </xsl:template>
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="//*[matches(name(), 'Code')]">
        <xsl:copy>
            <code>
                <xsl:value-of select="."/>
            </code>
            <schemeName>
                <xsl:value-of select="@codingScheme"/>
            </schemeName>
            <displayName>
                <LocalizedString>
                    <xsl:attribute name="value">
                        <xsl:value-of select="@displayName"/>
                    </xsl:attribute>
                </LocalizedString>
            </displayName>
        </xsl:copy>
    </xsl:template>
  

Комментарии:

1. Вы не можете создавать объявления пространств имен, используя xsl: атрибут — пространства имен и атрибуты — это не одно и то же в модели данных XSLT. Соответствующий процессор XSLT выбросит это. В XSLT 2.0 используйте xsl:namespace.

2. Спасибо. Я внес изменения.

3. Но это не отвечает на ваш вопрос, потому что вы не запрашивали таблицу стилей XSLT…