Создание оператора SQL INSERT из данных файла XML - PullRequest
0 голосов
/ 09 июня 2019

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

Мои файлы XML включают, например, следующие теги (описывающие надгробие):

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="http://www.stoa.org/epidoc/schema/latest/tei-epidoc.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:lang="en">
    <teiHeader>
        <fileDesc>
            <titleStmt>
                <title>Funerary inscription for Marcellus, a smith</title>
            </titleStmt>
            <publicationStmt>
                <authority>I.Sicily</authority>
                <idno type="TM">491539</idno>
            </publicationStmt>
            <sourceDesc>
                <msDesc>
                    <msIdentifier>
                        <country>Italy</country>
                        <region>Sicily</region>
                        <settlement>Catania</settlement>
                        <repository role="museum" ref="http://sicily.classics.ox.ac.uk/museum/018"
                            >Museo Civico di Catania </repository>
                        <idno type="inventory">390</idno>
                        <altIdentifier>
                            <settlement/>
                            <repository/>
                            <idno type="old"/>
                        </altIdentifier>
                    </msIdentifier>
                    <msContents>
                        <textLang mainLang="la">Latin </textLang>
                    </msContents>
                    <physDesc>
                        <objectDesc>
                            <supportDesc>
                                <support>
                                    <material n="marble"
                                        ref="http://www.eagle-network.eu/voc/material/lod/48.html"
                                        >marble </material>
                                    <objectType n="tabula"
                                        ref="http://www.eagle-network.eu/voc/objtyp/lod/257">tablet </objectType>
                                    <dimensions>
                                        <height unit="cm">29</height>
                                        <width unit="cm">33.5</width>
                                        <depth unit="cm">2.1</depth>
                                    </dimensions>
                                </support>
                            </supportDesc>
                        </objectDesc>
                    </physDesc>
                </msDesc>
            </sourceDesc>
        </fileDesc>
    </teiHeader>
<!-- lots more content that I cut away here -->
</TEI>

Я хотел бы извлечь из этого информацию и вставить ее в таблицу SQL.

Мой желаемый результат будет выглядеть так:

INSERT INTO tblObjects
(ObjectID, Title, TMid, Material, ObjectType, Height)
VALUES
('Funerary inscription for Marcellus, a smith', 491539, 'marble', 'tabula', 29);

Мой оригинальный - теперь решенный - проблема заключалась в следующем:

Я попытался установить метод вывода в текст после нескольких примеров, которые я нашел в сети, но это дает мне сообщение об ошибке «Не пробелы символы не допускаются в элементах схемы, кроме 'xs: appinfo' и «xs: документация». "

Я изменил формат файла на xsl, теперь он больше не жалуется на непробельные символы. Теперь я могу поместить текст в окончательный вывод. Следующее (вдохновленное вашими ответами) текущее состояние моего XSLT, а сейчас я хочу попытаться просто вставить значение заголовка, положение которого «TEI / teiHeader / fileDesc / titleStmt / title»:

<?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"
        encoding="UTF-8" 
        omit-xml-declaration="yes"
        indent="no"/>

    <xsl:template match="/">
        <xsl:text>INSERT INTO tblObjects</xsl:text>
        <xsl:text>(ObjectID, Title, TMid, Material, ObjectType, Height) VALUES (</xsl:text>
        <xsl:apply-templates select="root"/>    
        <xsl:text>);</xsl:text>
    </xsl:template>

    <xsl:template match="root">
        <xsl:value-of select="TEI/teiHeader/fileDesc/titleStmt/title"/>
    </xsl:template>

</xsl:stylesheet>

Это дает мне следующий вывод:

INSERT INTO tblObjects(ObjectID, Title, TMid, Material, ObjectType, Height) VALUES ();

Тем не менее, как вы можете видеть, он не вставляет значение заголовка. Я не уверен, почему это не работает (пока только пробую название).

1 Ответ

0 голосов
/ 09 июня 2019

Просто пройдитесь по дереву с шаблонами и объедините значения с необходимыми кавычками и запятыми для предложения VALUES SQL-запроса.Из-за множества вложенных структур XML, пути ancestor::* и descendant::* используются для извлечения значения конкретного узла.

Примечание. Это решение работает с файлами XML для одного teiHeader .Вам нужно будет адаптировать это решение или запустить другие сценарии XSLT для других типов.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:doc="http://www.tei-c.org/ns/1.0">

    <xsl:output method="text" encoding="UTF-8" omit-xml-declaration="yes" indent="no"/>

    <xsl:template match="/doc:TEI">
      <xsl:text>INSERT INTO tblObjects</xsl:text>
      <xsl:text>(ObjectID, Title, TMid, Material, ObjectType, Height)&#xa;VALUES&#xa;</xsl:text>
      <xsl:apply-templates select="doc:teiHeader/doc:fileDesc/doc:sourceDesc/doc:msDesc/doc:physDesc"/>
    </xsl:template> 

    <xsl:template match="doc:physDesc">
        <xsl:variable name="quote">&apos;</xsl:variable>
        <xsl:value-of select="concat('(', 
                                     $quote, ancestor::doc:fileDesc/doc:titleStmt/doc:title, $quote, ', ', 
                                     ancestor::doc:fileDesc/doc:publicationStmt/doc:idno[@type='TM'], ', ',
                                     $quote, normalize-space(descendant::doc:material), $quote, ', ',
                                     $quote, normalize-space(descendant::doc:objectType), $quote, ', ',
                                     descendant::doc:dimensions/doc:height,
                                     ')' 
                                    )"/>
    </xsl:template>

</xsl:stylesheet>

Онлайн-демонстрация

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