【问题标题】:Reverse-Engineering unknown XML based on known XSL基于已知 XSL 对未知 XML 进行逆向工程
【发布时间】:2010-09-16 23:26:46
【问题描述】:

解决了!

按照 Matti 的建议,我删除了自定义函数,一切都很好。

原帖:

我从今天开始是 XSLT 的新手,所以我相信这对你们中的许多人来说是不费吹灰之力的。无论如何:

我的任务是为我公司的网站创建一个小部件,该小部件使用第三方供应商提供的数据。

供应商拒绝向我们发送示例 XML 文件(甚至是一个只有元素标签的空白文件!)所以我正在尝试根据我在其中看到的内容重新创建 XML他们 - 确实 - 发送给我们的 XSLT。 (可笑性比比皆是

这是我们收到的(剥离的)XSLT 文件:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:myCustXslFunctions="urn:CustomXslFunctions">

  <xsl:variable name="NumberColumns" >1</xsl:variable>
  <xsl:variable name="PaperId" >1234567890ABCDEF</xsl:variable>

  <xsl:output method="html" version="1.0" encoding="UTF-8" indent="no" />
  <xsl:template match="/NewDataSet">
    <div><xsl:apply-templates select="/NewDataSet" mode="columns" /></div>
  </xsl:template>

  <xsl:template match="NewDataSet" mode="columns">
    <xsl:for-each select="Table[position() mod $NumberColumns  = 1 or $NumberColumns = 1]">
      <p>
        <xsl:for-each select=".|following-sibling::Table[position() &lt; $NumberColumns]">
          <span class="description">
            <xsl:element name="a">
              <xsl:attribute name="target">_blank</xsl:attribute>
              <xsl:attribute name="class" >description</xsl:attribute>
              <xsl:choose>
                <xsl:when test="retail='true'">
                  <xsl:attribute name="href">http://website/retail/?pid=<xsl:value-of select="$PaperId" />&#38;adid=<xsl:value-of select="paperitemid" /></xsl:attribute>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:attribute name="href">http://website/?pid=<xsl:value-of select="$PaperId" />&#38;adid=<xsl:value-of select="paperitemid" /></xsl:attribute>
                </xsl:otherwise>
              </xsl:choose>
              <xsl:choose>
                <xsl:when test="imageurl != ''">
                  <xsl:element name="img">
                    <xsl:attribute name="src"><xsl:value-of select="imageurl" /></xsl:attribute>
                    <xsl:attribute name="border">0</xsl:attribute>
                    <xsl:attribute name="class">thumbnail</xsl:attribute>
                  </xsl:element>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:element name="img">
                    <xsl:attribute name="src">http://website/thumbs/<xsl:value-of select="paperid" />_<xsl:value-of select="paperitemid" />_100.jpg</xsl:attribute>
                    <xsl:attribute name="border">0</xsl:attribute>
                    <xsl:attribute name="class">thumbnail</xsl:attribute>
                  </xsl:element>
                </xsl:otherwise>
              </xsl:choose>
              </xsl:element>
          </span>
        </xsl:for-each>
      </p>
      <p>
        <xsl:for-each select=".|following-sibling::Table[position() &lt; $NumberColumns]">
          <span class="description">
            <xsl:element name="a">
              <xsl:attribute name="target">_blank</xsl:attribute>
              <xsl:attribute name="class" >description</xsl:attribute>
              <xsl:choose>
                <xsl:when test="retail='true'">
                  <xsl:attribute name="href">http://website/?pid=<xsl:value-of select="$PaperId" />&#38;adid=<xsl:value-of select="paperitemid" /></xsl:attribute>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:attribute name="href">http://website/?pid=<xsl:value-of select="$PaperId" />&#38;adid=<xsl:value-of select="paperitemid" /></xsl:attribute>
                </xsl:otherwise>
              </xsl:choose>
              <xsl:choose>
                <xsl:when test="string-length(shortdescr) = 0"><xsl:value-of select="myCustXslFunctions:MakeNice(descr,20,20,'Left','true')" /></xsl:when>
                <xsl:otherwise><xsl:value-of select="myCustXslFunctions:MakeNice(shortdescr,20,20,'Left','true')" /></xsl:otherwise>
              </xsl:choose>
            </xsl:element>
          </span>
        </xsl:for-each>
      </p>
    </xsl:for-each>
  </xsl:template>
</xsl:transform>

我对 XML 进行逆向工程的微弱尝试:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="facepalm.xsl"?>
<NewDataSet>
  <Table>
    <paperid>123</paperid>
    <paperitemid>12345</paperitemid>
    <descr>facepalm of doom</descr>
    <shortdescr>facepalm</shortdescr>
    <retail>true</retail>
    <imageurl>http://website/facepalm.jpg</imageurl>
  </Table>
  <Table>
    <paperid>456</paperid>
    <paperitemid>67890</paperitemid>
    <descr>mega-sigh</descr>
    <shortdescr>sigh</shortdescr>
    <retail>true</retail>
    <imageurl>http://website/sigh.jpg</imageurl>
  </Table>
</NewDataSet>

毫无疑问,我忽略了一些简单的事情,但我在 XSLT 方面的新手身份已经使这个项目成为一个多小时的项目。

非常感谢任何帮助。

【问题讨论】:

  • 那么,你的任务是什么?您要对他们的 XML 执行 XSLT 转换吗?
  • 任务是修改他们的 XSL 以适应我们网站上内容框的需求,但是没有任何示例 XML,很难看到我们对设计的更改。

标签: xml xslt reverse-engineering


【解决方案1】:

我的猜测更像是:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="facepalm.xsl"?>
<NewDataSet>
 <Table>
  <paperid>123</paperid>
  <paperitemid>12345</paperitemid>
  <descr>failvendor</descr>
  <shortdescr>facepalm</shortdescr>
  <retail>true</retail>
  <imageurl>http://website/facepalm.jpg</imageurl>
 </Table>
 <Table>
  <paperid>456</paperid>
  <paperitemid>67890</paperitemid>
  <descr>is fail</descr>
  <shortdescr>sigh</shortdescr>
  <retail>true</retail>
  <imageurl>http://website/sigh.jpg</imageurl>
 </Table>
</NewDataSet>
  1. [] 不是指元素名称的一部分,而是指元素的位置。所以元素名称就是Table
  2. 您错过了 descrpaperid 元素。

XSLT 似乎在做的是将项目按列排列在列表中。是的,XSLT 就是这么复杂。

此外,如果定义了imageurl,它似乎忽略了paperidpaperitemid,如果提供了shortdescr,则忽略了descr。这可能会帮助您完成任务。

...如果没有实际的 XML,你应该如何测试它,顺便说一句?

【讨论】:

  • 我假设 PaperId 变量是在 XSLT 的第二行定义的。 / 从 标记中删除数字给了我这样的信息:“XSLT 转换期间出错:调用了未知的 XPath 扩展函数”/我同意,这很难测试。我们花了 2 天时间打了六通电话才拿到 XSLT 文件。
  • @jnpcl:似乎有一个名为PaperId 的变量和一个名为paperid 的元素。您得到的错误意味着 XML 是正确的;但是 XSLT 转换正在尝试调用在命名空间 urn:CustomXslFunctions 中定义的名为 MakeNice 的自定义函数,而这可能丢失了。
【解决方案2】:

在一般情况下,仅给定 XSLT 就不可能确定输入 XML 文件的结构

虽然在这种情况下,您可能已经能够对基于 XSLT 的 XML 描述进行逆向工程,但在一般情况下,它不可能正确完成。在这种情况下,这是可能的,因为模板很小并且使用了for-each

XSLT 是 declarative,这意味着您描述如果遇到某些节点会发生什么,但包含从不调用或以不明显方式调用的模板当然是合法的。类似地,&lt;xsl:apply-templates /&gt; 的使用无法了解已知元素中包含哪些元素。

例如:

<xsl:template match="book">
    <xhtml:div class="book">
        <xsl:apply-templates />
    </xhtml:div>
</xsl:template>

<xsl:template match="title">
    <xhtml:h1><xsl:value-of select="."/></xhtml:h1>
</xsl:template>

<xsl:template match="chapter/title">
    <xhtml:h2><xsl:value-of select="."/></xhtml:h2>
</xsl:template>

书有标题吗?书有章节吗?章节甚至有标题吗? 我们不知道也不可能知道。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    相关资源
    最近更新 更多