简体   繁体   English

即使我不知道节点的名称,也可以使用XSLT匹配XML文档中的任何节点

[英]Match any node in XML document using XSLT even if I don't know the names of the nodes

How do I transform a XML doc using XSTL when I don't know the names of the nodes. 当我不知道节点的名称时,如何使用XSTL转换XML文档。 So basically it should work universally, with any XML document. 所以基本上它应该普遍适用于任何XML文档。

Let's say I got this XML document: 假设我得到了这个XML文档:

<?xml version="1.0"?>
<?xml-stylesheet href="transform.xsl" type="text/xsl" ?>
<!DOCTYPE cinema [
<!ELEMENT a (b*)>
<!ELEMENT b (c,d,e)>
<!ELEMENT c (#PCDATA)>
<!ELEMENT d (#PCDATA)>
<!ELEMENT e (#PCDATA)>
]>

<cinema>
<movie>
    <actor>Some actor</actor>
    <title>Some title</title>
    <year>Some year</year>
</movie>
</cinema>

How would I create an HTML table out of this? 我将如何创建一个HTML表格呢? I know I can match the root element like this: 我知道我可以像这样匹配根元素:

<xsl:template match="/">

Then I select all movies like this: 然后我选择所有这样的电影:

<xsl:for-each select="/*/*">

But how to I know get one row for each movie with three columns for actor, title & year? 但是我如何知道为每部电影获得一行,其中三列为演员,头衔和年份? Especially since the XML file (movie) should be able to maybe only have 2 children or 5. 特别是因为XML文件(电影)应该只能有2个孩子或5个孩子。

+++EDIT+++ +++编辑+++

If I do this: 如果我这样做:

<tr>
    <td><xsl:value-of select="."/></td>
</tr>

I get each movie's details in one row. 我把每部电影的细节都放在一行。 This is almost close to what I want to achieve. 这几乎接近我想要达到的目标。 But how to I spread out the movie details over three columns in that row? 但是如何在该行的三列中展开电影细节呢?

If you know you will always have three levels of elements (root, children and grandchildren) then something like this should do it: 如果你知道你将永远有三个级别的元素(根,子和孙),那么这样的事情应该这样做:

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

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

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

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

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

The / template matches the document node , /* matches first-level element children of the document node (ie the root element of the document), /*/* matches second-level children, etc. / template匹配文档节点/*匹配文档节点的第一级元素子节点(即文档的根元素), /*/*匹配二级子节点等。

<xsl:apply-templates/> (with no select ) will apply matching templates to all the child nodes of the current node, which includes child elements, text nodes, comments and processing instructions. <xsl:apply-templates/> (没有select )将匹配模板应用于当前节点的所有子节点,其中包括子元素,文本节点,注释和处理指令。 As a result, you may need the root template to be 因此,您可能需要根模板

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

to select only child elements . 仅选择子元素

sample XML: 示例XML:

<?xml version="1.0" encoding="utf-8"?>
<cinema>
  <movie>
    <actor>Some actor</actor>
    <title>Some title</title>
    <year>Some year</year>
  </movie>
  <movie>
    <actor>Someother actor</actor>
    <title>Someother title</title>
    <year>Someother year</year>
  </movie>
</cinema>

XSLT: XSLT:

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

    <xsl:template match="/">
      <table>
        <xsl:for-each select="*/*">
          <xsl:if test="position()=1">
            <tr>
              <th>actor</th>
              <th>title</th>
              <th>year</th>
            </tr>
          </xsl:if>
          <tr>
            <xsl:for-each select="actor|title|year">
              <td>
                <xsl:value-of select="."/>
              </td>
            </xsl:for-each>
          </tr>
        </xsl:for-each>
      </table>
    </xsl:template>
</xsl:stylesheet>

Output: 输出:

<?xml version="1.0" encoding="utf-8"?>
<table>
  <tr>
    <th>actor</th>
    <th>title</th>
    <th>year</th>
  </tr>
  <tr>
    <td>Some actor</td>
    <td>Some title</td>
    <td>Some year</td>
  </tr>
  <tr>
    <td>Someother actor</td>
    <td>Someother title</td>
    <td>Someother year</td>
  </tr>
</table>

Use : 用途

<xsl:template match="movie">
 <!-- Specify your tr-producing code here -->
</xsl:template>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM