如何使用XSL从XML创建XML?

14

如何使用XSL从XML中创建另一个XML文件?

我尝试了这样做,但没有得到结果。

Test.xml

<Address>
  <name> Alex</name>
  <lastname>Mathew</lastname>
</Address>

测试.xsl

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<Address>
      <FirstName><xsl:value-of select="name" /></FirstName>
      <LastName><xsl:value-of select="lastname" /></LastName>
</Address>
</xsl:template>

</xsl:stylesheet>

我需要这样的输出

<Address>
  <FirstName> Alex</FirstName>
  <LastName>Mathew</LastName>
</Address>

我试图在我的asp页面(test.asp)中进行转换。

<%
'Load XML
set xml = Server.CreateObject("Microsoft.XMLDOM")
xml.async = false
xml.load(Server.MapPath("Test.xml"))

'Load XSL
set xsl = Server.CreateObject("Microsoft.XMLDOM")
xsl.async = false
xsl.load(Server.MapPath("Test.xsl"))

'Response.Write(xml.transformNode(xsl))
'Response.ContentType = "text/plain; charset=UTF-8"

 Set doc = Server.CreateObject("Msxml2.DOMDocument.3.0")   
 doc.async = False  
 doc.loadXML(xml.transformNode(xsl))  

response.write xml.transformNode(xsl)

response.write doc.getElementsByTagName("FirstName").item(0).text
%>

请帮我解决这个问题

3个回答

19

你可能还想在样式表中添加一个 output 指令:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="/Address">
  <Address>
    <FirstName><xsl:value-of select="name" /></FirstName>
    <LastName><xsl:value-of select="lastname" /></LastName>
  </Address>
</xsl:template>

</xsl:stylesheet>

这会导致输出带有前导的xml声明:

<?xml version="1.0" ?>

17
问题在于"/",而不是根元素(或"文档元素")。
按层次结构,"/"比文档元素(在您的情况下为<Address>)高一个级别。因此,这个问题是:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/Address">
    <Address>
      <FirstName><xsl:value-of select="name" /></FirstName>
      <LastName><xsl:value-of select="lastname" /></LastName>
    </Address>
  </xsl:template>
</xsl:stylesheet>

实际上会起作用。注意微小的差别吗?更好的写法是这样的:Nicer

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- the identity template (copies your input verbatim) -->
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>

  <!-- special templates only for things that need them -->
  <xsl:template match="name">
    <FirstName><xsl:value-of select="." /></FirstName>
  </xsl:template>

  <xsl:template match="lastname">
    <LastName><xsl:value-of select="." /></LastName>
  </xsl:template>

</xsl:stylesheet>

2
使用<xsl:apply-templates select="node()|@*"/>而不是 xsl:value-of更加优美。 - Daniel Haley
1
@DevNull 这是有争议的。一般而言,是的;但就特定情况而言,其实并不是。 - Tomalak

4

为了更好地阐明Tomalak发布的内容:在DOM层次结构中,XML文档的根元素位于顶层元素之上。很容易混淆这两者。考虑以下XML文档:

<!-- This is a node - yes, comments are nodes.  -->
<root>
   <child/>
</root>
<!-- This is also a node.  -->

这个文档的根节点有三个子节点:一个注释节点,一个元素节点和另一个注释节点。顶层元素命名为root,因为创建XML实例文档的人都这样做,以延续文档根和顶层元素之间的混淆(特别是如果他们在XML教育中仍在使用“node”表示“element”时)。
这就引出了Tomalak所描述的“更好”的模板更好的原因之一。如果扩展身份转换,则XSLT在文档中只会更改您已为其构建模板的元素。文档中的其他所有节点都将不变地复制。因此,如果您的输入文档在顶级元素周围有注释,如上例所示,则它们不会从输出中删除,就像您只实现匹配Address元素的模板一样。
当然,如果您希望输出不包括注释,那也很容易实现;只需不实现身份转换即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接