在DOCTYPE XSLT 2.0 Saxon9he中插入ENTITY声明 [英] Inserting ENTITY declarations in DOCTYPE XSLT 2.0 Saxon9he

查看:79
本文介绍了在DOCTYPE XSLT 2.0 Saxon9he中插入ENTITY声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的任务是将XML文档分解为单独的工作包.我唯一遇到麻烦的部分是在DOCTYPE中插入图形实体声明,如下所示:

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

(不必在意实体名称的扩展名,在这里就是这样做的方式.)无论如何,实体将由在主XML文件中找到的所有 @boardno 构造而成.在< figure> < graphic> 中,即< graphic boardno ="IMAGE001.jpg"/>

我一直在使用< xsl:result-document> 来写出doctype,但是我不知道如何在其中获取实体.

我尝试了LexEv,但是得到了 net.sf.saxon.trans.XPathException:无法实例化com.andrewjwelch.lexev.LexEv类(它有一个公共的零参数构造函数吗?)联系了安德鲁,他说LexEv不再受支持,也不是我需要的工具,因为LexEv用于保存实体,而不是用于将其写入文件.

解决方案

就像Kay博士建议的那样,您可以使用DOE(禁用输出转义)手动创建它.

这与我过去使用的内容类似.我通常要做的是使用Python创建实体声明,然后将它们作为参数传递给样式表.

我使用xsl:key,所以不会得到重复的声明.

此外,您可能可以重构表示法数据的确定方式.尤其是当符号始终与文件扩展名相同时.

示例...

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:何时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:何时test ="matches(@boardno,'\.tif','i')">< xsl:text disable-output-escaping ="yes"><![CDATA ["NDATA ccitt4>]]>& #xA;</xsl:text></xsl:when>< xsl:何时test ="matches(@boardno,'\.cgm','i')">< xsl:text disable-output-escaping ="yes"><![CDATA ["NDATA cgm>]]]> #xA;</xsl:text></xsl:when>< xsl:何时test ="matches(@boardno,'\.jpe?g','i')">< xsl:text disable-output-escaping ="yes"><![CDATA ["NDATA jpg>]]]> #xA;</xsl:text></xsl:when>< xsl:otherwise>< xsl:message终止=是">未知图形扩展:< 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系统"IMAGE001.jpg" NDATA jpg><!ENTITY IMAGE002.jpg系统"IMAGE002.jpg" NDATA jpg><!ENTITY IMAGE003.jpg系统"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

I am tasked with breaking up an XML document into individual work packages. The only part I am having trouble with is inserting graphic entity declarations in the DOCTYPE like so:

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

(Never mind the extension in the entity name, that's how they do it here.) Anyway, the entities will be constructed from all the @boardno that are found in the main XML file which could be in a <figure> or a <graphic> i.e. <graphic boardno="IMAGE001.jpg"/>

I've been using <xsl:result-document> to write out the doctype, but I have no idea how to get the entities in there.

I tried LexEv but I get net.sf.saxon.trans.XPathException: Failed to instantiate class com.andrewjwelch.lexev.LexEv (does it have a public zero-argument constructor?) I contacted Andrew and he said that LexEv is no longer supported and not the tool I need, anyway, since LexEv is for preserving entities and not for writing them to a file.

解决方案

Like Dr. Kay suggested, you could create it by hand using DOE (disable-output-escaping).

Here's something similar to what I've used in the past. What I normally do though is create the entity declarations using Python and then pass them in as a parameter to the stylesheet.

I use an xsl:key so I don't get duplicate declarations.

Also, you could probably refactor how the notational data is determined; especially if the notation is always the same as the file extension.

Example...

XML Input

<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 Output

<!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>

Fiddle: http://xsltfiddle.liberty-development.net/gVhDDyQ

这篇关于在DOCTYPE XSLT 2.0 Saxon9he中插入ENTITY声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆