XSLT to generate html tags specified in XML

2019-02-19 10:57发布

So this may be a strange request but I'll give it a go. I have an xml document

<?xml version="1.0" encoding="utf-8" ?>
<Page>
  <ID>Site</ID>
  <Object>
    <ID>PostCode</ID>
    <Type>div</Type>
    <Class>display-label</Class>
    <Value>PostCode</Value>
  </Object>
  <Object>
    <ID>PostCodeValue</ID>
    <Type>div</Type>
    <Class>display-field</Class>
    <Value>$PostCode</Value>
  </Object>
</Page>

and I'm using this XSL to transform it into a html page

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <xsl:output method="html" indent="yes"/>
  <xsl:template match="/">
    <html>
      <head>
      </head>
      <body>
        <xsl:for-each select="Page/Object">
          &lt;<xsl:value-of select="Type"/>&gt;
          <xsl:value-of select="Value"/>
          &lt;/<xsl:value-of select="Type"/>&gt;
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

As you can see I'm trying to generate the correct html tag dependent on the type node in the xml. The problem is "<" isn't accepted in the xsl and encoding it stops it from being recognised as a tag.

Any suggestions how I'd go about this?

Thanks in advance

标签: xslt
2条回答
何必那么认真
2楼-- · 2019-02-19 11:27

Use xsl:element to create an element node in the output document.

<xsl:element name="{Type}" >
<xsl:value-of select="Value"/>
</xsl:element>

Note: the curly braces in the name attribute may look strange, if you aren't familiar. It is an Attribute Value Template used to evaluate an XPATH expression inside of an attribute declaration.

Applied to your stylesheet:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <xsl:output method="html" indent="yes"/>
  <xsl:template match="/">
    <html>
      <head>
      </head>
      <body>
        <xsl:for-each select="Page/Object">
            <xsl:element name="{Type}" >
                <xsl:value-of select="Value"/>
            </xsl:element>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
查看更多
Deceive 欺骗
3楼-- · 2019-02-19 11:29

you need to wrap your "<" in a text node with disable-output-escaping like this:

<?xml version="1.0" encoding="utf-8"?><!-- DWXMLSource="temp.xml" -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="html" indent="yes"/>
  <xsl:template match="/">
    <html>
      <head>
      </head>
      <body>
        <xsl:for-each select="Page/Object">
          <xsl:text disable-output-escaping="yes">&lt;</xsl:text><xsl:value-of select="Type"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
          <xsl:value-of select="Value"/>
          <xsl:text disable-output-escaping="yes">&lt;/</xsl:text><xsl:value-of select="Type"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
查看更多
登录 后发表回答