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>

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

我可以做任何 xslt 版本,并且可能会使用一些工具,如 XmlSpy 或类似工具。

我确实在这里找到了一种类似的问题/答案XSLT 来查找一个 XML 中的值并替换另一个 XML 文件,但我对 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 文档的 pid
4

1 回答 1

2

假设 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>

至于您更改的输入,您将不得不调整,因此要匹配子元素值cat上的元素,parent您可以声明一个键<xsl:key name="cat-match" match="cat" use="parent"/>,然后key('cat-match', $word-list, $cat-doc)/@catid为我们提供我们需要引用的catid属性值。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主输入中的元素。其余不变:

<?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 在 Oxygen 中运行它时,针对 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>
于 2016-10-20T16:06:54.553 回答