我对xslt的了解是有限的,但是我已经花了好几个小时并尝试了许多不同的脚本而没有运气。 这是情节: 我们的服务器上有一个xml数据库文件,每次启动软件时都会读取一个软件。我们大约有10个用户使用此文件。新条目存储在本地的类似文件中,我们需要更新服务器文件以包含每周新的本地存储条目。 我已经上传了本地文件的上传功能。上载的文件存储在数据库文件上方的目录中。两个文件的名称相同,但存储在不同的目录中。
这是我最接近的事情,从这个网站复制一个前solutin,只是更改名称。 这里的示例文件只有很少的条目用于测试目的。
“原始”XML:companyroutes.xml
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xml" href="merge2.xsl"?>
<companyroutes>
<route name="ENGMEKCH">ENGM OKSAT L996 SVD EKCH</route>
</companyroutes>
上传的XML:/upload/companyroutes.xml
<?xml version="1.0" encoding="utf-8"?>
<companyroutes>
<route name="ENVAENBR">ENVA GEVLI Z108 ROXET ENBR</route>
<route name="ENGMEKCH">ENGM OKSAT L996 SVD EKCH</route>
<route name="ABCDEFGH">ABCD TULLA L666 BAREN EFGH</route>
</companyroutes>
这是xsl合并脚本:merge2.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="fileName" select="'/upload/companyroutes.xml'" />
<xsl:param name="updates" select="document($fileName)" />
<xsl:variable name="updateRoute" select="$updates/companyroutes/route" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="companyroutes">
<xsl:copy>
<xsl:apply-templates select="route[not(@id = $updateRoute/@id)]" />
<xsl:apply-templates select="$updateRoute" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我需要包含的另外两个功能是只复制到原始版本的独特Childs,并且能够像我们今天在这个网址上一样在浏览器中查看原始文件:[http://www.xxxxx.org/cr/ companyroutes.xml] [1] 当我尝试在第二个.xsl文件中插入链接进行合并时,我在网址上看不到任何信息。
以下是在网页上转换xml到HTML表格的cr.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="/">
<html>
<body>
<h2>BBL - CompanyRoutes</h2>
<table border="1" cellspacing="0" cellpadding="2">
<tr>
<th>Route Name</th>
<th>Route</th>
</tr>
<xsl:for-each select="//route">
<tr>
<td><xsl:value-of select="./@name"/></td>
<td><xsl:value-of select="./text()"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:0)
这里有两个问题。
首先,在您的合并XSLT中,您正在执行此操作
<xsl:apply-templates select="route[not(@id = $updateRoute/@id)]" />
您正在匹配@id属性,但在XML中它似乎是应该使用的@name属性。因此声明应该如下所示
<xsl:apply-templates select="route[not(@name = $updateRoute/@name)]" />
您还谈到在浏览器中查看它,并查看您链接到的XML,您在XML的顶部有两个xml样式表处理指令(尽管您只在问题的XML示例中显示一个)
<?xml-stylesheet type="text/xsl" href="cr.xsl"?>
<?xml-stylesheet type="text/xml" href="merge2.xsl"?>
这表明您可能期望应用两个转换。 cr.xsl 应用于 merge2.xsl 转换的结果。我不相信这是可能的。即使有可能,也不会覆盖原始XML。它正在创建一个全新的XML文档显示。
你可以做的是将两个XSLT样式表合并为一个,并使用它,如果你纯粹想在浏览器中看到合并的结果
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="fileName" select="'upload.xml'"/>
<xsl:param name="updates" select="document($fileName)"/>
<xsl:variable name="updateRoute" select="$updates/companyroutes/route"/>
<xsl:template match="companyroutes">
<html>
<body>
<h2>BBL - CompanyRoutes</h2>
<table border="1" cellspacing="0" cellpadding="2">
<tr>
<th>Route Name</th>
<th>Route</th>
</tr>
<xsl:for-each select="route[not(@name = $updateRoute/@name)]|$updateRoute">
<xsl:sort select="@name"/>
<tr>
<td>
<xsl:value-of select="./@name"/>
</td>
<td>
<xsl:value-of select="./text()"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
当然,如果您确实想要使用合并覆盖原始XML,那么使用此方法是不可能的。在XML中添加 xml-stylesheet 处理指令不会导致原始XML被覆盖。 (请记住,转换是在客户端上,在浏览器中完成的,但您的文件存储在服务器上。)
您将不得不使用服务器语言(如PHP或ASP.Net)或其他方式调查服务器上的转换,具体取决于您当前使用的架构。