Вставка объявлений ENTITY в DOCTYPE XSLT 2.0 Saxon9he - PullRequest
1 голос
/ 07 апреля 2020

Мне поручено разбить документ XML на отдельные рабочие пакеты. Единственная часть, с которой у меня возникают проблемы - это вставка объявлений сущностей graphi c в DOCTYPE следующим образом:

<!DOCTYPE frntcover PUBLIC "-//USA-DOD//DTD TM Assembly REV C" "production.dtd" [
<!ENTITY IMAGE001.jpg SYSTEM "IMAGE001.jpg" NDATA jpg>
]>

(не берите в голову расширение имени сущности, вот как они это делают здесь.) В любом случае сущности будут построены из всех @boardno, найденных в основном файле XML, которые могут быть в <figure> или <graphic>, т. е. <graphic boardno="IMAGE001.jpg"/>

, которые я использовал <xsl:result-document> чтобы выписать doctype, но я понятия не имею, как туда ввести сущности.

Я попробовал LexEv, но я получил net.sf.saxon.trans.XPathException: Failed to instantiate class com.andrewjwelch.lexev.LexEv (does it have a public zero-argument constructor?) Я связался с Эндрю, и он сказал, что LexEv больше не поддерживается и В любом случае, это не тот инструмент, который мне нужен, поскольку LexEv предназначен для сохранения сущностей, а не для записи их в файл.

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

Как предположил доктор Кей, вы можете создать его вручную, используя DOE (disable-output-escaping).

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

Я использую ключ xsl:, чтобы не получать повторяющиеся объявления.

Кроме того, вы могли бы, вероятно, реорганизовать способ определения нотационных данных; особенно если запись всегда совпадает с расширением файла.

Пример ...

XML Ввод

<frntcover>
    <graphic boardno="IMAGE001.jpg"/>
    <figure boardno="IMAGE001.jpg"/>
    <graphic boardno="IMAGE002.jpg"/>
    <graphic boardno="IMAGE003.jpg"/>
</frntcover>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="_gd_gnbrs" match="*[@boardno]" use="@boardno"/>

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

  <xsl:template match="/*">
    <xsl:call-template name="generate_doctype">
      <xsl:with-param name="root" select="local-name()"/>
      <xsl:with-param name="pubid" select="'-//USA-DOD//DTD TM Assembly REV C'"/>
      <xsl:with-param name="sysid" select="'production.dtd'"/>
    </xsl:call-template>
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="generate_doctype">
    <xsl:param name="root"/>
    <xsl:param name="pubid"/>
    <xsl:param name="sysid"/>
    <xsl:text disable-output-escaping="yes">&#xA;<![CDATA[<!DOCTYPE ]]></xsl:text>
    <xsl:value-of select="$root"/>
    <xsl:choose>
      <xsl:when test="string($pubid)">
        <xsl:value-of select="concat(' PUBLIC &quot;',$pubid,'&quot;')" disable-output-escaping="yes"/>
      </xsl:when>
      <xsl:when test="string($sysid)">
        <xsl:text> SYSTEM</xsl:text>
      </xsl:when>
    </xsl:choose>
    <xsl:if test="string($sysid)">
      <xsl:value-of select="concat(' &quot;',$sysid,'&quot;')" disable-output-escaping="yes"/>
    </xsl:if>
    <xsl:text disable-output-escaping="yes"><![CDATA[ []]>&#xA;</xsl:text>
    <xsl:for-each select="//*[@boardno][count(.|key('_gd_gnbrs',@boardno)[1])=1]">
      <xsl:apply-templates select="." mode="ent_decs"/>
    </xsl:for-each>
    <xsl:text disable-output-escaping="yes"><![CDATA[]>]]>&#xA;</xsl:text>
  </xsl:template>

  <xsl:template match="*" mode="ent_decs">
    <xsl:text disable-output-escaping="yes"><![CDATA[<!ENTITY ]]></xsl:text>
    <xsl:value-of select="concat(@boardno,' SYSTEM &quot;',@boardno)" disable-output-escaping="yes"/>
    <xsl:choose>
      <xsl:when test="matches(@boardno,'\.tif','i')">
        <xsl:text disable-output-escaping="yes"><![CDATA[" NDATA ccitt4>]]>&#xA;</xsl:text>        
      </xsl:when>
      <xsl:when test="matches(@boardno,'\.cgm','i')">
        <xsl:text disable-output-escaping="yes"><![CDATA[" NDATA cgm>]]>&#xA;</xsl:text>
      </xsl:when>
      <xsl:when test="matches(@boardno,'\.jpe?g','i')">
        <xsl:text disable-output-escaping="yes"><![CDATA[" NDATA jpg>]]>&#xA;</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:message terminate="yes">UNKNOWN GRAPHIC EXTENSION: "<xsl:value-of select="@boardno"/>"</xsl:message>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

XML Выход

<!DOCTYPE frntcover PUBLIC "-//USA-DOD//DTD TM Assembly REV C" "production.dtd" [
<!ENTITY IMAGE001.jpg SYSTEM "IMAGE001.jpg" NDATA jpg>
<!ENTITY IMAGE002.jpg SYSTEM "IMAGE002.jpg" NDATA jpg>
<!ENTITY IMAGE003.jpg SYSTEM "IMAGE003.jpg" NDATA jpg>
]>
<frntcover>
   <graphic boardno="IMAGE001.jpg"/>
   <figure boardno="IMAGE001.jpg"/>
   <graphic boardno="IMAGE002.jpg"/>
   <graphic boardno="IMAGE003.jpg"/>
</frntcover>

Скрипка: http://xsltfiddle.liberty-development.net/gVhDDyQ

1 голос
/ 08 апреля 2020

Saxon имеет расширение saxon:doctype для добавления DTD к выходному документу: см. http://www.saxonica.com/documentation/index.html#! Extensions / инструкции / doctype

Но для этого требуется Saxon-PE или выше .

Единственный другой вариант - создать его «вручную» и вывести его с помощью disable-output-escaping. Или выполните некоторую постобработку, используя инструмент преобразования «простой текст», такой как Perl или awk.

...