必须有一种通用的方法来转换某些分层XML,例如:
<element1 A="AValue" B="BValue">
<element2 C="DValue" D="CValue">
<element3 E="EValue1" F="FValue1"/>
<element3 E="EValue2" F="FValue2"/>
</element2>
...
</element1>
进入展平的XML(html),沿途拾取所选属性,并为成为列标题的属性提供不同的标签。
<table>
<tr>
<th>A_Label</th>
<th>D_Label</th>
<th>E_Label</th>
<th>F_Label</th>
</tr>
<tr>
<td>AValue</td>
<td>DValue</td>
<td>EValue1</td>
<td>FValue1</td>
</tr>
<tr>
<td>AValue</td>
<td>DValue</td>
<td>EValue2</td>
<td>FValue2</td>
</tr>
<table>
好的,所以由于属性重新标记,没有通用的解决方案,但你明白了我的意思。我刚刚开始使用所有的XSLT / XPATH,所以我会及时解决它,但任何线索都会有用。
答案 0 :(得分:5)
我不是百分之百确定你要做什么,但是如果你的element1,element2和element3是一致的嵌套,这个解决方案可能会有效。
<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="xml" indent="yes"/>
<xsl:template match="/">
<table>
<xsl:apply-templates select="//element3"></xsl:apply-templates>
</table>
</xsl:template>
<xsl:template match="element3">
<tr>
<td><xsl:value-of select="../../@A"/></td>
<td><xsl:value-of select="../../@B"/></td>
<td><xsl:value-of select="../@C"/></td>
<td><xsl:value-of select="../@D"/></td>
<td><xsl:value-of select="@E"/></td>
<td><xsl:value-of select="@F"/></td>
</tr>
<xsl:apply-templates select="*"></xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
我需要一个类似的XSLT,但深度不详,我就是这样做的。
首先,为生成的HTML表/ def列表添加一个包装器,并调用模板mode =“puke”来展平我们的XML树:
<xsl:element name="div">
<xsl:attribute name="class" select="puke" />
<xsl:apply-templates select="$notice" mode="puke" />
</xsl:element>
这里我们匹配每个节点以显示其内容(例如text())及其属性。我们递归地做这件事。我使用了dl / dt / dd,因为我的源代码树是一棵复杂的树,无法作为一个扁平化。
<!-- @description:
Display all field from the notice so the customer can tell what he want
-->
<xsl:template match="node()" mode="puke">
<xsl:message>
puking : <xsl:value-of select="local-name( . )" />
</xsl:message>
<xsl:element name="dl">
<xsl:element name="dt">
<xsl:attribute name="class">tagName</xsl:attribute>
<xsl:value-of select="local-name( . )" />
</xsl:element>
<xsl:element name="dd">
<xsl:attribute name="class">tagText</xsl:attribute>
<xsl:value-of select="text()" /></xsl:element>
<xsl:element name="dl">
<xsl:attribute name="class">attr</xsl:attribute>
<!-- display attribute -->
<xsl:apply-templates select="@*" />
</xsl:element>
</xsl:element>
<!-- recursive call on node() -->
<xsl:apply-templates select="./*" mode="puke" />
</xsl:template>
匹配给定节点的属性并显示它们。
CSS用于格式化生成的HTML:
<style>
.puke {
background-color: #BDD6DE;
clear: both;
}
.tagName, .attrName {
float: left;
}
.tagText, .attrText {
clear: right;
}
</style>
答案 2 :(得分:0)
我们已经从Oracle数据库中读取了一个Pro * C程序,它调用了一个perl脚本,该脚本依次执行一些Java从上述数据库中提取XML格式的数据,用于调用批处理文件以执行一些vbscript FTP文件到其他服务器。我真的希望在Fortran做点什么。
答案 3 :(得分:0)
原始问题需要澄清:
在XSLT中,可以编写非常通用的变换器,但是当您考虑任何已知的限制时,编写样式表来转换文档通常要容易得多。
答案 4 :(得分:0)
我使用了下面模板的扩展版本来压缩结构化XML。警告:原始版本中有一些特定于案例的代码(它实际上将XML转换为CSV),我刚刚剥离,我没有测试此版本。
它的基本工作方式应该是明确的:它打印没有节点子节点的所有内容,否则递归调用具有子节点的node()上的模板。我认为它不像现在那样正确处理属性和注释,但这不应该很难解决。
<?xml version="1.0" encoding="UTF-8"?>
<!-- XSL template to flatten structured XML, before converting to CSV. -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:apply-templates select="//yourElementsToFlatten"/>
</xsl:template>
<xsl:template match="//yourElementsToFlatten">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:choose>
<!-- If the element has multiple childs, call this template
on its children to flatten it-->
<xsl:when test="count(child::*) > 0">
<xsl:apply-templates select="@*|node()"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:value-of select="text()" />
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>