从一个 xml 中查找值以更新另一个 xml

Lookup values from one xml to update another xml

我需要在一个 xml 中查找多个值,如下所示:

<cat catid="some_generic_text_followed_by_something_specific1" pid="x1">
</cat>
</cat><cat catid="some_generic_text_followed_by_something_specific1" pid="x2">
</cat>
<cat catid="some_generic_text_followed_by_something_specific2" pid="x3">
</cat>
<cat catid="some_generic_text_followed_by_something_specific2" pid="x4">
</cat>
<cat catid="some_generic_text_followed_by_something_specific3" pid="x5">
</cat>

所以任务是识别像 "specific1" 和 "specific2" 这样的词,并找到属于这些多个关键字的所有 pid 值。在这种情况下,我找到了 x1、x2、x3、x4,但没有找到 x5。

然后我必须查找另一个有很多节点的 xml:

<prod prod-id="x1">
    <display-name xml:lang="x-default">some text</display-name>
</prod>
<prod prod-id="x2">
    <display-name xml:lang="x-default">some more text</display-name>
</prod>
<prod prod-id="x5">
    <display-name xml:lang="x-default">some text</display-name>
</prod>

并在您看到 "some text" 之前批量更新相同的文本,然后是 "inserted keyword" 和那里的内容。所以第一个例子,它会说 "inserted keyword some text"。本质上,我在前面加上文字。

我可以做任何 xslt 版本并且可能会使用像 XmlSpy 或类似的工具。

我确实在此处 question/answer 找到了类似的东西 但我对 xslt 的了解还不足以对我的示例进行修改。

更新

我对上面的第一个 xml 做了一个小修正:它实际上是:

<cat catid="c1">
   <parent>specific1</parent>
</cat>
<cat catid="c2">
   <parent>specific1</parent>
</cat>
<cat catid="c3">
   <parent>specific1</parent>
</cat>
<cat catid="c4">
   <parent>specific2</parent>
</cat>
<cat catid="c5">
   <parent>specific2</parent>
</cat>
<cat-assign catid="c1" pid="x13"/>
<cat-assign catid="c1" pid="x14"/>
<cat-assign catid="c1" pid="x15"/>
<cat-assign catid="c2" pid="x24"/>
<cat-assign catid="c2" pid="x43"/>
<cat-assign catid="c2" pid="x44"/>
<cat-assign catid="c3" pid="x45"/>
<cat-assign catid="c4" pid="x27"/>
<cat-assign catid="c5" pid="x31"/>
<cat-assign catid="c5" pid="x32"/>
<cat-assign catid="c5" pid="x33"/>
<cat-assign catid="c5" pid="x34"/>
  1. 我需要寻找完全匹配 "specific1" 不使用 contains 关键字
  2. 然后找到catid(会有多个)
  3. 在同一个xml中,找出每个
  4. 最后查找用于查找另一个 xml 文档的 pid

假设 XSLT 3.0(当前版本的 XMLSpy 支持)您可以使用以下内容,假设您要操作的文档是主要输入并且其他文档的 URI 设置为参数 cat-uri:

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

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

    <xsl:param name="new" as="xs:string" select="'inserted keyword'"/>

    <xsl:param name="word-list" as="xs:string*" select="'specific1', 'specific2'"/>

    <xsl:param name="cat-doc" select="doc($cat-uri)"/>

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

    <xsl:key name="match" match="cat" use="some $word in $word-list satisfies contains(@catid, $word)"/>

    <xsl:key name="ref" match="prod[@prod-id]/display-name" use="../@prod-id"/>

    <xsl:variable name="pids" select="key('match', true(), $cat-doc)/@pid"/>

    <xsl:template match="key('ref', $pids)/text()">
        <xsl:value-of select="$new || ' ' || ."/>
    </xsl:template>

</xsl:stylesheet>

至于您更改的输入,您必须调整 keys,因此要匹配 parent 子元素值上的 cat 元素,您可以声明一个键 <xsl:key name="cat-match" match="cat" use="parent"/> 然后 key('cat-match', $word-list, $cat-doc)/@catid 为我们提供了我们需要引用的 cat-assigncatid 属性值。为此,我们可以定义另一个键 <xsl:key name="cat-assign" match="cat-assign" use="@catid"/>,然后 key('cat-assign', key('cat-match', $word-list, $cat-doc)/@catid, $cat-doc)/@pid 为我们提供值以引用主输入中的 prod 元素。其余不变:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">

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

    <xsl:param name="new" as="xs:string" select="'inserted keyword'"/>

    <xsl:param name="word-list" as="xs:string*" select="'specific1', 'specific2'"/>

    <xsl:param name="cat-doc" select="doc($cat-uri)"/>

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

    <xsl:key name="cat-match" match="cat" use="parent"/>

    <xsl:key name="cat-assign" match="cat-assign" use="@catid"/>

    <xsl:key name="ref" match="prod[@prod-id]/display-name" use="../@prod-id"/>

    <xsl:variable name="pids" select="key('cat-assign', key('cat-match', $word-list, $cat-doc)/@catid, $cat-doc)/@pid"/>

    <xsl:template match="key('ref', $pids)/text()">
        <xsl:value-of select="$new || ' ' || ."/>
    </xsl:template>

</xsl:stylesheet>

当我 运行 使用 Saxon 9.6 EE 对抗 cat.xml 时 运行

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <cat catid="c1">
        <parent>specific1</parent>
    </cat>
    <cat catid="c2">
        <parent>specific1</parent>
    </cat>
    <cat catid="c3">
        <parent>specific1</parent>
    </cat>
    <cat catid="c4">
        <parent>specific2</parent>
    </cat>
    <cat catid="c5">
        <parent>specific2</parent>
    </cat>
    <cat catid="c6">
        <parent>specific3</parent>
    </cat>
    <cat-assign catid="c1" pid="x13"/>
    <cat-assign catid="c1" pid="x1"/>
    <cat-assign catid="c1" pid="x15"/>
    <cat-assign catid="c2" pid="x24"/>
    <cat-assign catid="c2" pid="x43"/>
    <cat-assign catid="c2" pid="x44"/>
    <cat-assign catid="c3" pid="x45"/>
    <cat-assign catid="c4" pid="x27"/>
    <cat-assign catid="c5" pid="x31"/>
    <cat-assign catid="c5" pid="x2"/>
    <cat-assign catid="c5" pid="x33"/>
    <cat-assign catid="c5" pid="x34"/>
</root>

并且输入文档是

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <prod prod-id="x1">
        <display-name xml:lang="x-default">some text</display-name>
    </prod>
    <prod prod-id="x2">
        <display-name xml:lang="x-default">some more text</display-name>
    </prod>
    <prod prod-id="x5">
        <display-name xml:lang="x-default">some text</display-name>
    </prod>
</root>

结果是

<?xml version="1.0" encoding="UTF-8"?><root>
    <prod prod-id="x1">
        <display-name xml:lang="x-default">inserted keyword some text</display-name>
    </prod>
    <prod prod-id="x2">
        <display-name xml:lang="x-default">inserted keyword some more text</display-name>
    </prod>
    <prod prod-id="x5">
        <display-name xml:lang="x-default">some text</display-name>
    </prod>
</root>