搜索并替换一个元素,使用xslt 3,替换短语相同

search and replace an element, using xslt 3, the replacement phrase is the same

虽然我有一个 xml 文件作为输入,例如:

 <?xml version="1.0"?>
    <catalog>
       <book id="bk101">
          <author>Gambardella, Matthew</author>
          <title>XML Developer's Guide</title>
          <genre>Computer</genre>
          <price>44.95</price>
          <publish_date>2000-10-01</publish_date>
          <description>An in-depth look at creating applications 
          with XML.</description>
       </book>
       <book id="bk102">
          <author>Ralls, Kim</author>
          <title>Midnight Rain</title>
          <genre>Fantasy</genre>
          <price>5.95</price>
          <publish_date>2000-12-16</publish_date>
          <description>A former architect battles corporate zombies, 
          an evil sorceress, and her own childhood to become queen 
          of the world.</description>
       </book>
       <book id="bk103">
          <author>Corets, Eva</author>
          <title>Maeve Ascendant</title>
          <genre>Fantasy</genre>
          <price>5.95</price>
          <publish_date>2000-11-17</publish_date>
          <description>After the collapse of a nanotechnology 
          society in England, the young survivors lay the 
          foundation for a new society.</description>
       </book>
    </catalog>

并且我尝试找到在文件中或在 xsl 本身中包含以下信息的最佳方法:

value to search for: 
An in-depth look at creating applications with XML.
add location:
on the self
value to search for:
A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.
add location:
on the self

所以如果我制作一个逗号分隔的输入文件,它看起来像:

"An in-depth look at creating applications with XML.","on the self"
"A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.","on the self" 

我已经尝试使用 xslt 2,但我不断收到错误消息,例如不允许超过一个项目的序列作为变量 $search_phrase...

的值

期望的输出:

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>to be checked</description>
      <location>on the self</location>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>to be checked</description>
      <location>on the self</location>
   </book>
   <book id="bk103">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology 
      society in England, the young survivors lay the 
      foundation for a new society.</description>
   </book>
</catalog>

谁能给我一个 xslt-3.0 的例子,我可能可以替换上面的短语,并添加需要的元素,只要有匹配项?

我需要做什么:

在完整的xml文件中,有很多记录可以有相同的描述。我还需要对描述进行精确匹配:短语 "An in-depth look at creating applications with XML, authored by ..." 不应该匹配。在我的例子中,我也有一个描述,其中差异只是例如, "an in-depth look at creating applications with XML." 不应该也匹配。由于在我的代码中我使用小写字母,这也可能是问题所在,但不确定...只要有匹配项,就必须将搜索词中指定的位置添加到 location 元素中,该元素目前在任何位置都不存在记录在 xml.

这里有一个关于如何将 description 元素与作为参数传入的字符串序列进行比较的建议(但您可以从文件中读取它):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    expand-text="yes"
    version="3.0">

  <xsl:param name="new" as="xs:string" select='"on the self"'/>

  <xsl:param name="replace" as="xs:string" select="'to be checked'"/>

  <xsl:param name="search" as="xs:string*"
    select='"An in-depth look at creating applications with XML.",
"A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world."'/>

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="description[. = $search]">
      <xsl:copy>{$replace}</xsl:copy>
      <location>{$new}</location>
  </xsl:template>

</xsl:stylesheet>

http://xsltfiddle.liberty-development.net/eiQZDbk 时工作正常,但仅在编辑示例以将所有描述数据放在一行之后。

如果不是这样,则将模板更改为

  <xsl:template match="description[normalize-space() = $search]">
      <xsl:copy>{$replace}</xsl:copy>
      <location>{$new}</location>
  </xsl:template>

应该有帮助:http://xsltfiddle.liberty-development.net/eiQZDbk/1

如果您有多个术语相互关联,而不是某些 XML 格式似乎更适合构建数据,因此在

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    expand-text="yes"
    version="3.0">

  <xsl:param name="data-url" as="xs:string" select="'data.xml'"/>

  <!-- if you want to load from a file use xsl:param name="replacement-doc" select="doc($data-url)" -->
  <xsl:param name="replacement-doc">
    <root>
        <search>
            <term>An in-depth look at creating applications with XML.</term>
            <replacement>to be checked</replacement>
            <new>on the self</new>
        </search>
        <search>
            <term>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</term>
            <replacement>whatelse</replacement>
            <new>something</new>
        </search>
    </root>
  </xsl:param>

  <xsl:key name="search" match="search" use="term"/>

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="description[key('search', normalize-space(), $replacement-doc)]">
      <xsl:variable name="search" select="key('search', normalize-space(), $replacement-doc)"/>
      <xsl:copy>{$search/replacement}</xsl:copy>
      <location>{$search/new}</location>
  </xsl:template>

</xsl:stylesheet>

我已经提出了一些建议并调整了模板。在线示例位于 http://xsltfiddle.liberty-development.net/eiQZDbk/2。如评论中所述,您可以调整该方法以从单独的文件加载数据,而不是将其内嵌在 XSLT 中。