代码之家  ›  专栏  ›  技术社区  ›  tehDorf Aran Mulholland

从XSLT引用XML doctype实体

  •  1
  • tehDorf Aran Mulholland  · 技术社区  · 8 年前

    我正在尝试访问 !ENTITY XML文件中的元素 !DOCTYPE 使用XSL文件将XML转换为HTML时声明。在XML中,我有一个 widget 元素的属性与 !实体 名称,我希望XSLT将其转换为 !实体 的价值。

    XML文件

    <?xml version="1.0" encoding="utf-8"?>
    
    <!DOCTYPE root[
      <!ENTITY Widget_Manual "Widget_Manual_File_Name.pdf" >
    ]>
    
    <root>
      <!-- I want to convert this to "Widget_Manual_File_Name.pdf" in the transform -->
      <widget entityIdent="Widget_Manual" />
    </root>
    

    XSLT文件

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
      <xsl:template match="/">
        <html>
          <head />
          <body>
            <xsl:apply-templates />
          </body>
        </html>
      </xsl:template>
    
      <xsl:template match="widget">
        <!-- Embed PDF -->
        <object width="800" height="600" type="application/pdf">
          <xsl:attribute name="data">
            <!-- How do I access the !ENTITY's value using the @entityIdent attribute? -->
            <xsl:value-of select="@entityIdent" />
          </xsl:attribute>
        </object>
      </xsl:template>
    
    </xsl:stylesheet>
    

    实际产量

    <object width="800" height="600" type="application/pdf" data="Widget_Manual"></object>
    

    期望输出

    <object width="800" height="600" type="application/pdf" data="Widget_Manual_File_Name.pdf"></object>
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Mads Hansen    8 年前

    最好只使用XML中的一个实体,以便XML解析器在解析文档时为您扩展该实体。

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE root[
      <!ENTITY Widget_Manual "Widget_Manual_File_Name.pdf" >
    ]>
    <root>
        <!-- I want to convert this to "Widget_Manual_File_Name.pdf" in the transform -->
        <widget entityIdent="&Widget_Manual;" />
    </root>
    

    如果您没有对XML的控制权,并且希望在XSLT中执行查找/替换,那么您将不得不跳过一些循环。XSLT对已经分析过的XML进行操作,并且DTD内容在XML信息集中不能直接寻址。

    但是,您可以获得 base-uri() 然后使用 unparsed-text() 将XML作为字符串读取,然后使用 replace() 具有捕获组(或子字符串函数)以获取实体值的regex。

    可以使用以下XSLT2.0样式表:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:output indent="yes" />
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="@entityIdent">
            <xsl:attribute name="{name()}">
                <xsl:value-of select="replace(
                                       unparsed-text(base-uri()), 
                                       concat('.*!ENTITY ', ., ' &quot;(.+?)&quot;.*'),
                                       '$1', 
                                       's')"/>
            </xsl:attribute>
        </xsl:template>
    </xsl:stylesheet>