当我在 Oxygen 中使用 Saxon 运行以下模板时:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
expand-text="yes"
version="3.0">
<xsl:output indent="yes" method="xml" omit-xml-declaration="no" encoding="utf-8"/>
<xsl:template match="/">
<xsl:text>
</xsl:text>
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*">
<!-- On Martin's suggestion I should use node-name instead of name, so I have changed this, but the result is the same. -->
<xsl:value-of select="node-name()"/><xsl:text>
</xsl:text>
<xsl:apply-templates select="*"/>
</xsl:template>
</xsl:stylesheet>
在此 xml 上:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ddn PUBLIC "-//S1000D//DTD Data Dispatch Note 20050501//EN//XML" "http://www.s1000d.org/s1000d_2-2/xml_dtd/ddn/dtd/ddn.dtd">
<ddn>
<ddnc>
<modelic>ABC</modelic>
<sendid>AASSD</sendid>
<recvid>VVBBN</recvid>
<diyear>2024</diyear>
<seqnum>00001</seqnum>
</ddnc>
</ddn>
我得到以下输出:
<?xml version="1.0" encoding="utf-8"?>
ddn
ddnc
modelic
sendid
recvid
diyear
seqnum
很明显(至少对我来说),变换知道元素名称。
如果我将与元素匹配的模板更改为:
<xsl:template match="ddn">
<xsl:value-of select="node-name()"/><xsl:text>
</xsl:text>
<xsl:apply-templates select="*"/>
</xsl:template>
我得到以下内容,其中不包含任何元素名称:
<?xml version="1.0" encoding="utf-8"?>
ABC
AASSD
VVBBN
2024
0000
如果我删除文档类型声明并运行相同的转换,我会得到:
<?xml version="1.0" encoding="utf-8"?>
ddn
ABC
AASSD
VVBBN
2024
00001
现在已经找到root ddn了。 结论是dtd被转换使用了。
我宁愿忽略 dtd,也不愿尝试纠正其中的某些内容,因为 dtd 本来就不是我的。我只需要转换我得到的文件的内容,而这个问题中包含的xml只是实际文件的一小部分,但无论内容是什么,问题都是一样的。
那么我该如何解决这个问题呢?我是否需要在我的规则中添加一些命名空间(尽管 name 函数没有产生类似的东西),或者我可以告诉 Saxon 忽略 dtd 吗?看起来好像这是设置中的默认设置,但我怀疑这里还缺少其他东西。
我已经尝试使用带有内置 xslt 引擎的 XMLSpy 进行相同的转换,并且其行为方式相同。
如果我像这样添加 * 作为命名空间: 如果我将与元素匹配的模板更改为:
<xsl:template match="*:ddn">
<xsl:value-of select="node-name()"/><xsl:text>
</xsl:text>
<xsl:apply-templates select="*"/>
</xsl:template>
我得到:
<?xml version="1.0" encoding="utf-8"?>
ddn
ABC
AASSD
VVBBN
2024
00001
所以这可行,但是为什么?!?
建议?
我下载了一些 DTD,它有
<!ELEMENT ddn (rdf:Description?,ddnc,issdate,security,datarest?,
dispto,dispfrom,authrtn,mediaid?,remarks?,delivlst?) >
<!ATTLIST ddn
id ID #IMPLIED
xmlns CDATA #FIXED "http://www.s1000d.org/ddn"
%RDFDCATT; >
因此,基于此,对于任何非前缀元素,我希望在 XSLT 中声明
xpath-default-namespace="http://www.s1000d.org/ddn"
允许您选择和/或匹配 ddn
、ddnc
、issdate
等元素。