【问题标题】:How to get the unparsed entity attribute's value from XSLT?如何从 XSLT 中获取未解析的实体属性值?
【发布时间】:2010-10-02 21:18:29
【问题描述】:

我对 XSLT 和 XML 中未解析的实体有疑问。这是一个虚构的场景。首先我得到一个名为 doc.xml 的 XML 文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<!DOCTYPE document [
<!ELEMENT document (employee)*>
<!ELEMENT employee (lastname, firstname)>
<!ELEMENT lastname (#PCDATA)>
<!ELEMENT firstname (#PCDATA)>
<!NOTATION FOO SYSTEM 'text/xml'>
<!ENTITY ATTACHMENT SYSTEM 'attach.xml' NDATA FOO>
<!ATTLIST employee
       detail ENTITY #IMPLIED>
]>
<document>
    <employee detail="ATTACHMENT">
        <lastname>Bob</lastname>
        <firstname>Kevin</firstname>
    </employee>
</document>

在这个 XML 文件中,我对元素“employee”的属性“detail”使用了一个未解析的实体 (NDATA)。 attach.xml 是:

<?xml version="1.0" encoding="UTF-8"?>

<name>Bob Kevin</name>

然后我想使用 XSLT 生成输出以及嵌入的 attach.xml。我的 XSLT 文件名为 doc.xsl:

<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="document">
<Document>
        <xsl:apply-templates select="employee"/>
</Document>
</xsl:template>

<xsl:template match="employee">
Employee is:  <xsl:value-of select="@detail"/>
</xsl:template>

</xsl:stylesheet>

最后,我使用 Xalan 2.7.1 运行:

java -jar xalan.jar -IN doc.xml -XSL doc.xsl -OUT docout.xml

输出是:

<?xml version="1.0" encoding="UTF-8"?>
<Document>
Employee is:  ATTACHMENT
</Document>

这不是我想要的。我希望输出如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Document>
Employee is:  <name>Bob Kevin</name>
</Document>

我应该如何重写 XSLT 脚本以获得正确的结果?

【问题讨论】:

    标签: xml xslt dtd saxon xalan


    【解决方案1】:

    XSLT 2.0 中的解决方案

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="document">
    <Document>
            <xsl:apply-templates select="employee"/>
    </Document>
    </xsl:template>
    
    <xsl:template match="employee">
    Employee is:  <xsl:value-of select=
    "unparsed-text(unparsed-entity-uri(@detail))"/>
    </xsl:template>
    
    </xsl:stylesheet>
    

    请注意以下几点:

    1. XSLT 函数unparsed-text()unparsed-entity-uri() 的使用。

    2. attach.xml 文件的文本将在输出中转义。如果您想看到它未转义,请使用 &lt;xsl:output/&gt; 指令的 "cdata-section-elements" 属性。

    【讨论】:

    • 我在 Saxon-B 9.1.0.5 中收到警告,将样式表更改为 version="2.0" 有效。再次感谢!
    • @jscoot:谢谢,我从我的回答中纠正了这个意外错误。
    • 很遗憾,当使用Saxon API for .Net 时,这些函数将不起作用,Microsoft 解析器不会将未解析的实体通知给 Saxon。 XSLT 函数 unparsed-entity-uri() 和 unparsed-entity-public-id() 因此将不起作用,请参阅XML Parsing in .NET
    • @DaveAnderson,是的,很遗憾。除了 Saxon (J) 之外,人们仍然可以使用 MSXML3 或 MSXML6,这些 XSLT 处理器通过 XSLT 1.0 转换从下面@jscoot 的答案中产生想要的结果
    【解决方案2】:

    谢谢你,Dimitre Novatchev。根据您的回答,我在 XSLT 1.0 中得到了结果。有兴趣的可以参考http://www.xml.com/lpt/a/1243进行讨论。这是我的解决方案:

    <?xml version="1.0"?>
    
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="document">
    <Document>
            <xsl:apply-templates select="employee"/>
    </Document>
    </xsl:template>
    
    <xsl:template match="employee">
    Employee is: <xsl:copy-of select="document(unparsed-entity-uri(@detail))"/>
    </xsl:template>
    
    </xsl:stylesheet>
    

    请注意上面的以下行:

     <xsl:copy-of select="document(unparsed-entity-uri(@detail))"/>
    

    【讨论】:

    • @jscoot:太好了!但是,这是唯一可能的,因为您的 ENTITY 与 xml 文档相关联。在一般情况下(非 XML 文档),读取数据的唯一方法是使用 XSLT 2.0 函数 unparsed-text()。很高兴我能帮上忙。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 2012-07-02
    • 1970-01-01
    • 2017-05-29
    相关资源
    最近更新 更多