有没有办法在运行 xslt 时忽略引用的 dtd?

问题描述 投票:0回答:1

当我在 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>&#xa;</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>&#xa;</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>&#xa;</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>&#xa;</xsl:text>
     <xsl:apply-templates select="*"/>
</xsl:template>

我得到:

<?xml version="1.0" encoding="utf-8"?>
ddn
        ABC
        AASSD
        VVBBN
        2024
        00001

所以这可行,但是为什么?!?

建议?

xml xslt saxon dtd
1个回答
1
投票

我下载了一些 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
等元素。

© www.soinside.com 2019 - 2024. All rights reserved.