1

我正在使用 XSLT 转换 XML,并且我有一个带有一个 webdocuments 节点的 xml,该节点带有 webdocument 类型的节点

<webDocuments>
  <WebDocument>
    <id>808924</id>
    <fileName><![CDATA[file name]]></fileName>
    <filePath><![CDATA[.../201504/808924/filename.pdf]]></filePath>
    <hash><![CDATA[1c1bc9f96349fc954cba2dfb58f214b1]]></hash>
    <title><![CDATA[Primer document]]></title>
    <creationDate class="sql-timestamp">30/05/2012 15:49:57</creationDate>
  </WebDocument>
</webDocuments>

我正在尝试将文件路径节点值(文件系统)转换为 URL。上面有一个转换的示例,其中 param1 应该是 $hash,哈希节点值(在这种情况下为 1c1bc9f96349fc954cba2dfb58f214b1)和 param2 应该是 $id 在这种情况下 id 节点值 808924

<webDocuments>
  <WebDocument>
    <id>808924</id>
    <fileName><![CDATA[file name]]></fileName>
    <filePath>http://url.com/param1=$hash&param2=$id</filePath>
    <hash><![CDATA[1c1bc9f96349fc954cba2dfb58f214b1]]></hash>
    <title><![CDATA[Primer document]]></title>
    <creationDate class="sql-timestamp">30/05/2012 15:49:57</creationDate>
  </WebDocument>
</webDocuments>

总之

<filePath>http://url.com/param1=1c1bc9f96349fc954cba2dfb58f214b1&param2=808924

我尝试了很多东西,但没有得到预期的结果:

<xsl:template match="/webDocuments">
    <xsl:for-each select="/WebDocument">
    <xsl:value-of select="$hash"/>
        <xsl:value-of select="concat($baseUrl,$baseCAPUrl,$hash,'&amp;fileId&#61;')"/>

    </xsl:for-each>
</xsl:template>

总之,我的结果是获取一个节点值并用于生成另一个节点值。

提前致谢

4

2 回答 2

0

这应该是你需要的。没有真正的需要使用concat(),你可以在这里有连续的xsl:value-ofxsl:text节点来实现你所需要的。此外,尝试使用xsl:apply-templates使用xsl:for-each.

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

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

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

  <xsl:template match="filePath">
    <filePath>
         <!-- change below to the right value -->
      <xsl:variable name="baseUrl">http://url.com</xsl:variable>
         <!-- change below too, but I can't see where you use this in the URL -->
      <xsl:variable name="baseCAPUrl">/CAP/</xsl:variable>
      <xsl:value-of select="$baseUrl"/>
      <xsl:text>/</xsl:text>
      <xsl:value-of select="$baseCAPUrl"/>
      <xsl:text>?param1=</xsl:text>
      <xsl:value-of select="../hash"/>
      <xsl:text>param2=</xsl:text>
      <xsl:value-of select="../id"/>
    </filePath>
  </xsl:template>

  <!-- XSL identity -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

给出:

<?xml version="1.0" encoding="UTF-8"?>
<webDocuments>
  <WebDocument>
    <id>808924</id>
    <fileName>file name</fileName>
    <filePath>http://url.com//CAP/?param1=1c1bc9f96349fc954cba2dfb58f214b1param2=808924</filePath>
    <hash>1c1bc9f96349fc954cba2dfb58f214b1</hash>
    <title>Primer document</title>
    <creationDate class="sql-timestamp">30/05/2012 15:49:57</creationDate>
  </WebDocument>
</webDocuments>
于 2013-10-30T23:20:46.777 回答
0

首先要注意的是您的 XML 格式不正确,因为这一行

<filePath>http://url.com/param1=$hash&param2=$id</filePath>

&需要在这里逃脱。它应该看起来像这样

<filePath>http://url.com/param1=$hash&amp;param2=$id</filePath>

无论如何,在回答您的问题时,您似乎希望将 filePath 中的“变量”替换为使用同名元素的 XML 中的实际值。

您已将其标记为 XSLT2.0,这很好,因为您可以在此处使用xsl:analyze-string来查找您的“变量”,例如 $hash

<xsl:analyze-string select="." regex="\$\w+">

在此,您可以指定在找到“匹配子字符串”时要执行的操作。在这种情况下,您希望找到与您刚刚匹配的变量同名的元素(减去 $ 前缀)。

<xsl:matching-substring>
    <xsl:value-of select="$WebDocument/*[local-name() = substring(current(), 2)]"/>
</xsl:matching-substring>

(在这种情况下, $WebDocument是指向当前WebDocument元素的变量)

对于“不匹配”字符串,您只需按原样输出它们

  <xsl:non-matching-substring>
     <xsl:value-of select="current()"/>
  </xsl:non-matching-substring>

试试这个 XSLT

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

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="filePath">
      <xsl:variable name="WebDocument" select=".."/>
      <xsl:copy>
         <xsl:analyze-string select="." regex="\$\w+">
            <xsl:matching-substring>
               <xsl:value-of select="$WebDocument/*[local-name() = substring(current(), 2)]"/>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
               <xsl:value-of select="current()"/>
            </xsl:non-matching-substring>
         </xsl:analyze-string>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

这应该输出以下内容

<webDocuments>
    <WebDocument>
      <id>808924</id>
      <fileName>file name</fileName>
      <filePath>http://url.com/param1=1c1bc9f96349fc954cba2dfb58f214b1&amp;param2=808924</filePath>
      <hash>1c1bc9f96349fc954cba2dfb58f214b1</hash>
      <title>Primer document</title>
      <creationDate class="sql-timestamp">30/05/2012 15:49:57</creationDate>
  </WebDocument>
</webDocuments>

请注意此处使用XSLT 标识模板,以按原样输出所有其他节点。

于 2013-10-30T23:46:19.847 回答