当前位置 : 主页 > 网络推广 > seo >

从另一个节点的属性值中指定的路径检索XML节点

来源:互联网 收集:自由互联 发布时间:2021-06-16
从这个XML源: ?xml version="1.0" encoding="utf-8" ?ROOT STRUCT COL order="1" nodeName="FOO/BAR" colName="Foo Bar" / COL order="2" nodeName="FIZZ" colName="Fizz" / /STRUCT DATASET DATA FIZZtestFizz/FIZZ FOO BARtestBar/BAR LIBtestLib/LIB
从这个XML源:

<?xml version="1.0" encoding="utf-8" ?>
<ROOT>
  <STRUCT>
    <COL order="1" nodeName="FOO/BAR" colName="Foo Bar" />
    <COL order="2" nodeName="FIZZ" colName="Fizz" />
  </STRUCT>

  <DATASET>
    <DATA>
      <FIZZ>testFizz</FIZZ>
      <FOO>
        <BAR>testBar</BAR>
        <LIB>testLib</LIB>
      </FOO>
    </DATA>
    <DATA>
      <FIZZ>testFizz2</FIZZ>
      <FOO>
        <BAR>testBar2</BAR>
        <LIB>testLib2</LIB>
      </FOO>
    </DATA>
  </DATASET>
</ROOT>

我想生成这个HTML:

<html>
  <head>
    <title>Test</title>
  </head>
  <body>
    <table border="1">
      <tr>
        <td>Foo Bar</td>
        <td>Fizz</td>
      </tr>
      <tr>
        <td>testBar</td>
        <td>testFizz</td>
      </tr>
      <tr>
        <td>testBar2</td>
        <td>testFizz2</td>
      </tr>
    </table>
  </body>
</html>

这是我目前拥有的XSLT:

<?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="/ROOT">
    <html>
      <head>
        <title>Test</title>
      </head>
      <body>
        <table border="1">
          <tr>
            <!--Generate the table header-->
            <xsl:apply-templates select="STRUCT/COL">
              <xsl:sort data-type="number" select="@order"/>
            </xsl:apply-templates>
          </tr>
          <xsl:apply-templates select="DATASET/DATA" />
        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="COL">
    <!--Template for generating the table header-->
    <td>
      <xsl:value-of select="@colName"/>
    </td>
  </xsl:template>

  <xsl:template match="DATA">
    <xsl:variable name="pos" select="position()" />
    <tr>
      <xsl:for-each select="/ROOT/STRUCT/COL">
        <xsl:sort data-type="number" select="@order"/>
        <xsl:variable name="elementName" select="@nodeName" />
        <td>
          <xsl:value-of select="/ROOT/DATASET/DATA[$pos]/*[name() = $elementName]" />
        </td>
      </xsl:for-each>
    </tr>
  </xsl:template>

</xsl:stylesheet>

它几乎可以工作,我的问题是从STRUCT块的“nodeName”属性值中指定的路径中检索正确的DATA节点.

这是一个不使用任何扩展的纯XSLT 1.0解决方案:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <html>
    <head>
      <title>Test</title>
    </head>
    <body>
      <table border="1">
        <xsl:apply-templates select="*/STRUCT"/>
        <xsl:apply-templates select="*/DATASET/DATA"/>
      </table>
    </body>
  </html>
 </xsl:template>

 <xsl:template match="STRUCT">
  <tr>
    <xsl:apply-templates select="COL"/>
  </tr>
 </xsl:template>

 <xsl:template match="COL">
  <td><xsl:value-of select="@colName"/></td>
 </xsl:template>

 <xsl:template match="DATA">
      <tr>
        <xsl:apply-templates select="/*/STRUCT/*/@nodeName">
         <xsl:with-param name="pCurrentNode" select="."/>
        </xsl:apply-templates>
      </tr>
 </xsl:template>

 <xsl:template match="@nodeName" name="getNodeValue">
   <xsl:param name="pExpression" select="string(.)"/>
   <xsl:param name="pCurrentNode"/>

   <xsl:choose>
    <xsl:when test="not(contains($pExpression, '/'))">
      <td><xsl:value-of select="$pCurrentNode/*[name()=$pExpression]"/></td>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="getNodeValue">
        <xsl:with-param name="pExpression"
          select="substring-after($pExpression, '/')"/>
        <xsl:with-param name="pCurrentNode" select=
        "$pCurrentNode/*[name()=substring-before($pExpression, '/')]"/>
      </xsl:call-template>
    </xsl:otherwise>
   </xsl:choose>

 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的XML文档时:

<ROOT>
  <STRUCT>
    <COL order="1" nodeName="FOO/BAR" colName="Foo Bar" />
    <COL order="2" nodeName="FIZZ" colName="Fizz" />
  </STRUCT>

  <DATASET>
    <DATA>
      <FIZZ>testFizz</FIZZ>
      <FOO>
        <BAR>testBar</BAR>
        <LIB>testLib</LIB>
      </FOO>
    </DATA>
    <DATA>
      <FIZZ>testFizz2</FIZZ>
      <FOO>
        <BAR>testBar2</BAR>
        <LIB>testLib2</LIB>
      </FOO>
    </DATA>
  </DATASET>
</ROOT>

产生了想要的正确结果:

<html>
    <head>
        <title>Test</title>
    </head>
    <body>
        <table border="1">
            <tr>
                <td>Foo Bar</td>
                <td>Fizz</td>
            </tr>
            <tr>
                <td>testBar</td>
                <td>testFizz</td>
            </tr>
            <tr>
                <td>testBar2</td>
                <td>testFizz2</td>
            </tr>
        </table>
    </body>
</html>
网友评论