Xml 当源文档没有DOCTYPE时,如何使XSLT工作?

Xml 当源文档没有DOCTYPE时,如何使XSLT工作?,xml,xslt,Xml,Xslt,我有以下XML文档: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ONIXmessage SYSTEM "http://www.editeur.org/onix/2.1/short/onix-iternational.dtd"> <ONIXmessage release="2.1"> <header> <m174>Some Publisher</m174>

我有以下XML文档:

<?xml version="1.0"  encoding="UTF-8"?>
<!DOCTYPE ONIXmessage SYSTEM "http://www.editeur.org/onix/2.1/short/onix-iternational.dtd">
<ONIXmessage release="2.1">
  <header>
    <m174>Some Publisher</m174>
    <m182>20090622</m182>
  </header>
  <product>
    <a001>160258186X</a001>
    <a002>03</a002>
    <productidentifier>
      <b221>15</b221>
      <b244>9781602581869</b244>
    </productidentifier>
    <b246>02</b246>
    <b012>BB</b012>
    <title>
      <b202>01</b202>
      <b203>The Acts of the Apostles</b203>
      <b030>The</b030>
      <b031>Acts of the Apostles</b031>
      <b029>Four Centuries of Baptist Interpretation</b029>
    </title>
  </product>
</ONIXmessage>

因为您的输入中没有@refname或@shortname,所以将输入复制到输出时保持不变正是此转换所要做的。如果它打算做其他事情,你需要解释这是什么。您还没有向我们展示DTD,但它可以通过各种方式影响结果;例如,它可能会声明@refname或@shortname属性的默认值。如果是这样的话,那么由于样式表的行为取决于这些属性,没有这些属性就无法工作。

您可以很容易地在这样的预处理步骤中将DOCTYPE添加到XML文档中:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"
 doctype-system=
 "http://www.editeur.org/onix/2.1/reference/onix-international.dtd"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>
<!DOCTYPE ONIXmessage
  SYSTEM "http://www.editeur.org/onix/2.1/reference/onix-international.dtd">
<ONIXmessage release="2.1">
   <header>
      <m174>Some Publisher</m174>
      <m182>20090622</m182>
   </header>
   <product>
      <a001>160258186X</a001>
      <a002>03</a002>
      <productidentifier>
         <b221>15</b221>
         <b244>9781602581869</b244>
      </productidentifier>
      <b246>02</b246>
      <b012>BB</b012>
      <title>
         <b202>01</b202>
         <b203>The Acts of the Apostles</b203>
         <b030>The</b030>
         <b031>Acts of the Apostles</b031>
         <b029>Four Centuries of Baptist Interpretation</b029>
      </title>
   </product>
</ONIXmessage>

当此转换应用于不带DOCTYPE的XML文档时(在本例中为已从中删除DOCTYPE的提供的XML文档):


某出版商
20090622
160258186X
03
15
9781602581869
02
BB
01
使徒行传
这个
使徒行传
四个世纪的浸信会诠释
结果是相同的XML文档,但正确添加了DOCTYPE

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"
 doctype-system=
 "http://www.editeur.org/onix/2.1/reference/onix-international.dtd"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>
<!DOCTYPE ONIXmessage
  SYSTEM "http://www.editeur.org/onix/2.1/reference/onix-international.dtd">
<ONIXmessage release="2.1">
   <header>
      <m174>Some Publisher</m174>
      <m182>20090622</m182>
   </header>
   <product>
      <a001>160258186X</a001>
      <a002>03</a002>
      <productidentifier>
         <b221>15</b221>
         <b244>9781602581869</b244>
      </productidentifier>
      <b246>02</b246>
      <b012>BB</b012>
      <title>
         <b202>01</b202>
         <b203>The Acts of the Apostles</b203>
         <b030>The</b030>
         <b031>Acts of the Apostles</b031>
         <b029>Four Centuries of Baptist Interpretation</b029>
      </title>
   </product>
</ONIXmessage>

某出版商
20090622
160258186X
03
15
9781602581869
02
BB
01
使徒行传
这个
使徒行传
四个世纪的浸信会诠释

现在,您可以在预处理阶段的结果上成功应用转换。

对于此特定转换,请注意,ONIX 2.1已被弃用,Editeur将不提供服务。您必须在本地存储DTD。行业机构Editeur的注释

我会发布DTD,但它只有几百KB。DTD为每个标记定义了两个名称——一个短名称(如b221)和一个引用名称(如ProductIDType)。此XSLT将使用短标记的文件转换为使用引用标记的文件。结构和数据是相同的,标记名只是更改而已。如果我在没有DOCTYPE的输入文件上运行它,那么短标记名不会转换为引用标记。因此,您正在确认此转换所需的信息都在DTD中。这让我想知道你为什么要问这个问题。因为我以前从未使用过XSLT,请原谅。是否有一个选项可以说“如果输入文档缺少DOCTYPE,那么假设它是XXX”@JamesHealy:是的,您可以添加缺少的DOCTYPE——请参阅我的答案。
<!DOCTYPE ONIXmessage
  SYSTEM "http://www.editeur.org/onix/2.1/reference/onix-international.dtd">
<ONIXmessage release="2.1">
   <header>
      <m174>Some Publisher</m174>
      <m182>20090622</m182>
   </header>
   <product>
      <a001>160258186X</a001>
      <a002>03</a002>
      <productidentifier>
         <b221>15</b221>
         <b244>9781602581869</b244>
      </productidentifier>
      <b246>02</b246>
      <b012>BB</b012>
      <title>
         <b202>01</b202>
         <b203>The Acts of the Apostles</b203>
         <b030>The</b030>
         <b031>Acts of the Apostles</b031>
         <b029>Four Centuries of Baptist Interpretation</b029>
      </title>
   </product>
</ONIXmessage>