Как создать xml-элементы, если они отсутствуют в xslt?

#xml #xslt

#xml #xslt

Вопрос:

У меня есть три xml-структуры, которые необходимо очистить и гомогенизировать, создав элемент, если он отсутствует, или выбрав его, если он уже существует.

Структура A содержит большинство элементов, которые мне нужны:

 <biblStruct>
           <analytic>
              <title type="label">Gronemann/Maaß/Peters/Schrader 2001</title>
              <title type="titel">Körper und Schrift. Beiträge zum 16. Nachwuchskolloquium der
                 Romanistik, Leipzig, 14.-17. Juni 2000</title>
              <idno>6677</idno>
              <idno>6677</idno>
              <author>
                 <persName>Gronemann, Claudia;Maaß, Christiane;Peters, Sabine A.;Schrader,
                    Sabine</persName>
              </author>
           </analytic>
           <monogr>
              <title type="label">Gronemann/Maaß/Peters/Schrader 2001</title>
              <title type="titel">Körper und Schrift. Beiträge zum 16. Nachwuchskolloquium der
                 Romanistik, Leipzig, 14.-17. Juni 2000</title>
              <idno type="standortsign">UB Bern;SUB Göttingen</idno>
              <author>
                 <persName>Gronemann, Claudia;Maaß, Christiane;Peters, Sabine A.;Schrader,
                    Sabine</persName>
              </author>
              <imprint>
                 <publisher>Romanistischer Verlag</publisher>
                 <pubPlace>
                    <placeName>Bonn</placeName>
                 </pubPlace>
                 <date>2001</date>
              </imprint>
           </monogr>
           <relatedItem type="enhalt">
              <ref>Objekt 3257 / Biographien-Werke</ref>
           </relatedItem>
           <note type="faustdb">biogra</note>
           <note type="objektart">Bibliographie</note>
           <note type="objektart">Bibliographie</note>
           <note type="erstellt">
              <date>2016-09-18T00:00:00.000</date>
           </note>
           <note type="letztebearb">
              <date>2016-09-18T00:00:00.000</date>
           </note>
        </biblStruct>
  

В то время как в структуре B отсутствует элемент publisher внутри imprint :

 <biblStruct>
           <analytic>
              <title type="label">Volmer 2001</title>
              <title type="titel">Die Gebrechen des Lebens. Zur Körpererfahrung in
                 Korrespondenzen des 18. Jahrhunderts</title>
              <idno>3257</idno>
              <idno>3257</idno>
              <author>
                 <persName>Volmer, Annett</persName>
              </author>
           </analytic>
           <monogr>
              <title type="label">Volmer 2001</title>
              <title type="titel">Die Gebrechen des Lebens. Zur Körpererfahrung in
                 Korrespondenzen des 18. Jahrhunderts</title>
              <idno type="standortsign">UB Basel: AP IX 5844</idno>
              <author>
                 <persName>Volmer, Annett</persName>
              </author>
              <imprint>
                 <biblScope unit="sammelwerkin">Objekt 6677 / Biographien-Werke</biblScope>
                 <biblScope unit="sammelwerkseiten">138-149</biblScope>
              </imprint>
           </monogr>
           <note type="faustdb">biogra</note>
           <note type="objektart">Bibliographie</note>
           <note type="objektart">Bibliographie</note>
           <note type="erstellt">
              <date>2005-01-19T00:00:00.000</date>
           </note>
           <note type="letztebearb">
              <date>2016-10-10T00:00:00.000</date>
           </note>
           <note type="kategorie">Briefkultur, Netzwerke,
              Transfer;Wissen(schaft)sgeschichte/Medizin</note>
        </biblStruct>
  

Я хотел бы иметь возможность создавать этот publisher элемент, вложенный внутрь imprint , только когда он отсутствует — я имею дело с огромным списком, который содержит очень разнообразные записи.

То же самое относится к структуре C, в которой не хватает еще большего количества элементов:

 <biblStruct>
           <analytic>
              <idno>24587</idno>
              <idno>24587</idno>
              <author>
                 <persName>Person aus Ref-Tabelle</persName>
              </author>
           </analytic>
           <note type="faustdb">Publik</note>
           <note type="objektart">Rezensionen</note>
           <note type="objektart">Rezensionen</note>
        </biblStruct>
  

В этом случае я хотел бы добавить после следующих элементов analytic :

 <monogr>
              <imprint>
                 <publisher></publisher>
              </imprint>
           </monogr>
  

Таким образом, результат должен быть:

 <biblStruct>
           <analytic>
              <idno>24587</idno>
              <idno>24587</idno>
              <author>
                 <persName>Person aus Ref-Tabelle</persName>
              </author>
           </analytic>
           <monogr>
              <imprint>
                 <publisher></publisher>
              </imprint>
           </monogr>
           <note type="faustdb">Publik</note>
           <note type="objektart">Rezensionen</note>
           <note type="objektart">Rezensionen</note>
        </biblStruct>
  

Не имеет значения, пусты ли элементы в данный момент. Есть идеи, как я могу этого добиться?

Помните, что все эти xml-записи находятся в одном файле, и я пока не могу их отсортировать, поэтому мне нужно создать требуемые элементы с учетом того, существуют они уже или еще не существуют. Спасибо!

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

1. Один из фундаментальных принципов проектирования XML заключается в том, что элементы могут отсутствовать без негативных последствий и что отсутствие элемента указывает на то, что связанные данные недоступны. Не случайно, что запрос документа с помощью XPath на наличие элементов, которые не существуют, не является ошибкой, а просто возвращает пустой список. Создание пустых элементов «просто так» противоречило бы этому принципу. Это можно сделать, без проблем, но вопрос в том, действительно ли вам это нужно? Для чего?

2. Спасибо за ваш комментарий. Я хочу создать их, потому что надеюсь в будущем заполнить элементы значениями. На данный момент они могут быть пустыми, но они нужны мне для целей проверки и т.д. Спасибо.

3. » Мне нужно создать требуемые элементы с учетом того, существуют они уже или еще не существуют » Или вы могли бы просто создать их все, независимо от того, существуют они или нет — затем заполнить те, которые существуют, соответствующими значениями. Есть причина, по которой шаблон называется шаблоном.

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

Ответ №1:

Спасибо за ваши комментарии. Я попробовал это, и это сработало в первом случае:

 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs tei" version="2.0"
xmlns:tei="http://www.tei-c.org/ns/1.0">

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="tei:imprint[not(./tei:publisher)]">
    <xsl:copy>
        <xsl:element name="tei:publisher"> </xsl:element>
    </xsl:copy>

</xsl:template>
  

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

1. К вашему сведению, нет необходимости говорить <xsl:element name="tei:publisher"> . Просто скажите <tei:publisher> прямо. Намного короче и намного проще для чтения.

2. Кроме того, я бы, вероятно, использовал <xsl:if test="not(tei:publisher)">...</xsl:if> внутри обычного шаблона для tei:imprint . Таким образом, у вас было бы меньше особых случаев и вы имели бы полный контроль над порядком дочерних элементов.

3. Я не думаю, что это делает то, что вы хотите. Не следует ли скопировать другие элементы, которые существуют внутри imprint ? В любом случае, я подозреваю, что если вы продолжите использовать этот метод, ваша таблица стилей вскоре превратится в неуправляемый лес исключений.