如何处理 XSLT 中嵌入的 XML 标签?

发布于 2024-10-12 17:22:03 字数 1216 浏览 5 评论 0原文

我正在使用 XSLT 将 XML 转换为 HTML。我无法弄清楚如何处理嵌入的 XML 节点以进行格式化。例如,假设我有 XML 元素:

the Star Wars saga

但是,在 XLST 期间, 标记会被忽略,因此“Star Wars”在 HTML 输出中不会显示为斜体。有没有一个相对简单的方法来解决这个问题?

测试.xml:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="test.html.xsl"?>
<favoriteMovies>
    <favoriteMovie>the <i>Star Wars</i> saga</favoriteMovie>
</favoriteMovies>

测试.html.xsl:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" omit-xml-declaration="yes" />
    <xsl:template match="/">
      <html>
        <head />
          <body>
            <ul>
                <xsl:for-each select="favoriteMovies/favoriteMovie">
                    <li><xsl:value-of select="." /></li>
                </xsl:for-each>
            </ul>
          </body>
      </html>
    </xsl:template>
</xsl:stylesheet>

I am using XSLT to convert XML to HTML. I am having trouble figuring out how to deal with embedded XML nodes for formatting. For example, let's say I have the XML element:

<favoriteMovie>the <i>Star Wars</i> saga</favoriteMovie>

However, during XLST, the <i> tag gets ignored, so "Star Wars" is not italicized in the HTML output. Is there a relatively simple way to fix this?

test.xml:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="test.html.xsl"?>
<favoriteMovies>
    <favoriteMovie>the <i>Star Wars</i> saga</favoriteMovie>
</favoriteMovies>

test.html.xsl:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" omit-xml-declaration="yes" />
    <xsl:template match="/">
      <html>
        <head />
          <body>
            <ul>
                <xsl:for-each select="favoriteMovies/favoriteMovie">
                    <li><xsl:value-of select="." /></li>
                </xsl:for-each>
            </ul>
          </body>
      </html>
    </xsl:template>
</xsl:stylesheet>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

画尸师 2024-10-19 17:22:03

但是,在 XLST 期间, 标记会变得
被忽视,所以“星球大战”不是
在 HTML 输出中以斜体显示。是
有一个相对简单的方法来修复
这个?


您的问题在这里

<前><代码>

    ;

指令用于创建文本节点。在此过程中,它将将此 XSLT 指令的 select 属性中指定的 XPath 表达式的字符串值复制到输出。元素的字符串值是其所有文本节点后代的串联。

这就是获取报告输出的方式。

解决方案

使用< code>指令,复制其 select 属性中指定的所有节点:

<ul>
  <xsl:for-each select="favoriteMovies/favoriteMovie">
    <li><xsl:copy-of select="node()"/></li>
  </xsl:for-each>
</ul>

另一种解决方案,更符合 XSLT 的原则完全避免使用

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

 <xsl:template match="/">
  <html>
    <head />
    <body>
     <xsl:apply-templates/>
    </body>
  </html>
 </xsl:template>

 <xsl:template match="/*">
  <ul>
   <xsl:apply-templates/>
  </ul>
 </xsl:template>

 <xsl:template match="favoriteMovie">
  <li><xsl:copy-of select="node()"/></li>
 </xsl:template>
</xsl:stylesheet>

当上面定义的两个解决方案中的任何一个应用于提供的 XML 文档时< /strong>:

<favoriteMovies>
    <favoriteMovie>the 
        <i>Star Wars</i> saga
    </favoriteMovie>
</favoriteMovies>

产生了想要的正确结果:

<html>
    <head/>
    <body>
        <ul>
            <li>the 
                <i>Star Wars</i> saga
            </li>
        </ul>
    </body>
</html>

However, during XLST, the <i> tag gets
ignored, so "Star Wars" is not
italicized in the HTML output. Is
there a relatively simple way to fix
this?

Your problem is here:

<ul>
  <xsl:for-each select="favoriteMovies/favoriteMovie">
    <li><xsl:value-of select="."/></li>
  </xsl:for-each>
</ul>

The <xsl:value-of> instruction is used to create a text node. In doing so it copies to the output the string value of the XPath expression specified in the select attribute of this XSLT instruction. The string value of an element is the concatenation of all its text-node descendents.

So this is how you get the reported output.

Solution:

Use the <xsl:copy-of> instruction, which copies all the nodes that are specified in its select attribute:

<ul>
  <xsl:for-each select="favoriteMovies/favoriteMovie">
    <li><xsl:copy-of select="node()"/></li>
  </xsl:for-each>
</ul>

Another solution, more alligned with the principles of XSLT avoids using <xsl:for-each> at all:

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

 <xsl:template match="/">
  <html>
    <head />
    <body>
     <xsl:apply-templates/>
    </body>
  </html>
 </xsl:template>

 <xsl:template match="/*">
  <ul>
   <xsl:apply-templates/>
  </ul>
 </xsl:template>

 <xsl:template match="favoriteMovie">
  <li><xsl:copy-of select="node()"/></li>
 </xsl:template>
</xsl:stylesheet>

When any of the two solutions defined above are applied to the provided XML document:

<favoriteMovies>
    <favoriteMovie>the 
        <i>Star Wars</i> saga
    </favoriteMovie>
</favoriteMovies>

the wanted, correct result is produced:

<html>
    <head/>
    <body>
        <ul>
            <li>the 
                <i>Star Wars</i> saga
            </li>
        </ul>
    </body>
</html>
原谅过去的我 2024-10-19 17:22:03

您应该使用 xsl:copy 复制 i 节点。

http://msdn.microsoft.com/en-us/library/ms256128.aspx

    <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" omit-xml-declaration="yes" />
    <xsl:template match="/">
      <html>
        <head />
          <body>
            <xsl:apply-templates></xsl:apply-templates>        
          </body>
      </html>
    </xsl:template>
<xsl:template match="favoriteMovies">
  <ul>
    <xsl:apply-templates></xsl:apply-templates>
  </ul>  
</xsl:template>
  <xsl:template match="favoriteMovie">
    <li>      
      <xsl:apply-templates></xsl:apply-templates>
    </li>
  </xsl:template>
  <xsl:template match="i">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

You should use xsl:copy to copy the i node .

http://msdn.microsoft.com/en-us/library/ms256128.aspx

    <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" omit-xml-declaration="yes" />
    <xsl:template match="/">
      <html>
        <head />
          <body>
            <xsl:apply-templates></xsl:apply-templates>        
          </body>
      </html>
    </xsl:template>
<xsl:template match="favoriteMovies">
  <ul>
    <xsl:apply-templates></xsl:apply-templates>
  </ul>  
</xsl:template>
  <xsl:template match="favoriteMovie">
    <li>      
      <xsl:apply-templates></xsl:apply-templates>
    </li>
  </xsl:template>
  <xsl:template match="i">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
北城孤痞 2024-10-19 17:22:03

您应该使用“disable-output-escaping”属性。元素的一般格式是:

<xsl:value-of select="expression" disable-output-escaping="yes|no" />

“disable-output-escaping”是可选的。 “yes”表示特殊字符(如“<”)应按原样输出。 “no”表示特殊字符(如“<”)应输出为“<”。默认为“否”。

因此只需将您的代码更改为:

<xsl:template match="favoriteMovie">
  <xsl:copy-of select="node()" disable-output-escaping="yes"/>
</xsl:template>

You should use 'disable-output-escaping' attribute. The general format of element is:

<xsl:value-of select="expression" disable-output-escaping="yes|no" />

'disable-output-escaping' is optional. "yes" indicates that special characters (like "<") should be output as is. "no" indicates that special characters (like "<") should be output as "<". Default is "no".

Therefore just change your code to:

<xsl:template match="favoriteMovie">
  <xsl:copy-of select="node()" disable-output-escaping="yes"/>
</xsl:template>
枕梦 2024-10-19 17:22:03

有两件事需要注意。

第一的。确保在 CDATA

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="test.html.xsl"?>
<favoriteMovies>
    <favoriteMovie><![CDATA[the <i>Star Wars</i> saga]]></favoriteMovie>
</favoriteMovies>

Second 中筛选标签。禁用输出转义:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes" />
<xsl:template match="/">
  <html>
    <head />
      <body>
        <ul>
            <xsl:for-each select="favoriteMovies/favoriteMovie">
                <li><xsl:value-of select="." disable-output-escaping="yes" /></li>
            </xsl:for-each>
        </ul>
      </body>
  </html>
</xsl:template>

编辑:使用编辑器管理它,现在代码按应有的方式显示

编辑2:在代码中包含更改

编辑3:对于可能关心的人来说,问题的真正领域是关于构建电影信息,并且不是 html 数据。 HTML 仅用于标记目的,想象一下在 favoriteMovie 中有 html 标题标签,而相同的命名标签标题可能是 movies 数据库中的有效标签。这些标题显然必须有不同的解释。这证明使用 CDATA 然后在处理时禁用输出是合理的。

Two things to note.

First. Make sure tags are screened in CDATA

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="test.html.xsl"?>
<favoriteMovies>
    <favoriteMovie><![CDATA[the <i>Star Wars</i> saga]]></favoriteMovie>
</favoriteMovies>

Second. Disable output escaping:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes" />
<xsl:template match="/">
  <html>
    <head />
      <body>
        <ul>
            <xsl:for-each select="favoriteMovies/favoriteMovie">
                <li><xsl:value-of select="." disable-output-escaping="yes" /></li>
            </xsl:for-each>
        </ul>
      </body>
  </html>
</xsl:template>

EDIT: managed it with the editor, now the code is shown as it should

EDIT2: included changes in your code

EDIT3: To whom it may concern, the very domain of the problem in question is about structuring movies information, and not html data. HTML is there for markup purposes only, imagine having, say, html title tag inside favoriteMovie, whereas the same named tag title could be a valid tag in the movies database. These title's CLEARLY have to be interpreted differently. This justifies using CDATA and then disabling output when processing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文