XSLT 1.0:搜索属性并添加到父元素(第 2 部分)

XSLT 1.0: search an attribute and add to parent element (part-2)

使用 XSLT 1.0 我需要对此进行转换:


<wine id="_7" grape="chardonnay"> 
    <product>Carneros</product>
    <year>1997</year>
    <price>10.99</price>
    <Method context="_5" attributes="gccxml(msgid=237)">
        <Argument location="f0:13"/>
    </Method>
    <Field id="_3" context="_7" attributes="gccxml(msgid=239)"/>
    <Field id="_4" line="19" attributes=""/>
    <Method context="_8" attributes="">
        <Argument location="f0:13"/>
    </Method>
</wine>
  • into this:

    XML Output-1:

<wine grape="chardonnay" msgid="239">
   <product>Carneros</product>
   <year>1997</year>
   <price>10.99</price>
   <Method context="_5" attributes="gccxml(msgid=237)">
        <Argument location="f0:13"/>
    </Method>
    <Field id="3" context="_7" attributes="gccxml(msgid=239)"/>
    <Field id="4" line="19"/>
    <Method context="_8">
        <Argument location="f0:13"/>
    </Method>
</wine>

实现'XML Output-1'的逻辑如下: ================================================ ========== - 逻辑 1: ---------- 搜索与 wine[@id].

匹配的 'Field[@context]' 或 'Method[@context]' 节点
For instance: 
<wine id="_7" grape="chardonnay"> 
<Field id="_3" context="_7" attributes="gccxml(msgid=239)"/>

To conclude:
The wine[id="_7"] matches Field[context="_7"], so add the attributes="gccxml(msgid=239)"
in 'wine' element (i.e. msgid="239")

Result:
<wine grape="chardonnay" msgid="239">

- Logic 2:
----------
If 'Field' or 'Method' nodes includes attributes="" (null attribute),
then delete the attributes="" in output.

For Instance:
1. <Field id="4" line="19"/>
2. <Method context="_8">

In addition, I need to transfer this:

XML 输入-2


 <wine id="_5" grape="chardonnay"> 
        <product>Carneros</product>
        <year>1997</year>
        <price>10.99</price>
        <Field id="_9" line="19" attributes=""/>
        <Method context="_5" attributes="gccxml(msgid=235)">
            <Argument location="f0:13"/>
        </Method>
        <Field id="_3" context="_7" attributes="gccxml(msgid=239)"/>
        <Field id="_4" line="19" attributes=""/>
    </wine>

Into this

XML 输出-2:

<wine grape="chardonnay" msgid="235">
   <product>Carneros</product>
   <year>1997</year>
   <price>10.99</price>
   <Field id="_9" line="19"/>
   <Method context="_5" attributes="gccxml(msgid=235)">
        <Argument location="f0:13"/>
    </Method>
    <Field id="3" context="_7" attributes="gccxml(msgid=239)"/>
    <Field id="4" line="19"/>
</wine>   

search for either 'Field[@context]' or 'Method[@context]' nodes that matches the wine[@id].

使用 key - XSLT's built-in mechanism to handle cross-references. Once that's done, it's just a rerun of your previous question:

很容易做到

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="msg" match="Field|Method" use="@context"/>

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

<xsl:template match="/*">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:attribute name="msgid">
            <xsl:value-of select="substring-before(substring-after(key('msg', @id)/@attributes, 'msgid='), ')')"/>      
        </xsl:attribute>
        <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

已添加:

要删除 FieldMethod 元素的空属性,只需添加一个匹配它们的空模板:

<xsl:template match="@*[parent::Field or parent::Method][not (string())]"/>