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

时间:2016-10-20 14:54:59

标签: xml xslt xslt-3.0

我需要在一个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>

并在您看到带有“inserted keyword”的“some text”之后批量更新相同的文本,然后是那里的内容。所以在第一个例子中,它会说“插入关键字一些文本”。从本质上讲,我在文本前面。

我可以使用任何xslt版本,可能会使用XmlSpy等类似的工具。

我确实在XSLT to lookup values in one XML and replace in another XML file找到了类似的问题/答案,但我不明白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”而不是使用包含关键字
  2. 然后找到catid(会有多个)
  3. 在同一个xml中,找到每个
  4. 最后查找用于查找另一个xml doc
  5. 的pid

1 个答案:

答案 0 :(得分:2)

假设XSLT 3.0(当前版本的XMLSpy支持),您可以使用以下内容,假定您要操作的文档是主要输入,而另一个文档的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>

cat

对于您更改的输入,您必须调整keys,然后匹配parent子元素值上的<xsl:key name="cat-match" match="cat" use="parent"/>元素,您可以声明一个键{{1然后key('cat-match', $word-list, $cat-doc)/@catid为我们提供了我们需要引用的catid的{​​{1}}属性值。为此,我们可以定义另一个键cat-assign,然后<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

当我使用Saxon 9.6 EE在Oxygen里面运行那个cat.xml

<?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>

,输入文件为

<?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>