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>
已添加:
要删除 Field
和 Method
元素的空属性,只需添加一个匹配它们的空模板:
<xsl:template match="@*[parent::Field or parent::Method][not (string())]"/>
使用 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>
已添加:
要删除 Field
和 Method
元素的空属性,只需添加一个匹配它们的空模板:
<xsl:template match="@*[parent::Field or parent::Method][not (string())]"/>