XSLT:通过复制外部文件中具有属性值的标签来转换 xml 文件
XSLT : Transform xml file by duplicating tags having attribute value in external file
我有两个文件;
items.xml : 要转换的文件
<items>
<item cat="cat_id1">
<link>link1</link>
<link>link11</link>
</item>
<item cat="cat_id2">
<link>link2</link>
<link>link22</link>
</item>
<item cat="cat_id3">
<link>link3</link>
</item>
</items>
items_to_transforme.xml :包含要翻译的类别的标识符
<categories>
<categorie>cat_id1</categorie>
<categorie>cat_id3</categorie>
</categories>
我需要通过复制文件 items_to_transforme.xml 中具有 cat 属性值的标签来转换 items.xml,然后更改属性值
想要的结果:
<items>
<item cat="cat_id1">
<link>link1</link>
<link>link11</link>
</item>
<item cat="cat_id1-FR">
<link>link1</link>
<link>link11</link>
</item>
<item cat="cat_id2">
<link>link2</link>
<link>link22</link>
</item>
<item cat="cat_id3">
<link>link3</link>
</item>
<item cat="cat_id3-FR">
<link>link3</link>
</item>
</items>
我如何使用 xslt 执行此操作?我是 xslt 的新手,感谢您的帮助。
为第二个文档中的元素定义一个键,并将其用于您复制匹配元素的模板的匹配模式(例如,通过将处理委托给身份转换设置):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="categories-doc">
<categories>
<categorie>cat_id1</categorie>
<categorie>cat_id3</categorie>
</categories>
</xsl:param>
<xsl:key name="cat-key" match="categorie" use="."/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="item[key('cat-key', @cat, $categories-doc)]">
<xsl:next-match/>
<xsl:apply-templates select="." mode="change-id"/>
</xsl:template>
<xsl:mode name="change-id" on-no-match="shallow-copy"/>
<xsl:template mode="change-id" match="item/@cat">
<xsl:attribute name="{name()}" select=". || '-FR'"/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/gWEamLh/1 内联了第二个文档以确保示例的完整性,但当然可以使用 <xsl:param name="categories-doc" select="doc('categories.xml')"/>
。示例还使用 XSLT 3,身份转换是使用 xsl:mode
声明设置的,但当然对于 XSLT 2,您可以将其拼写为模板。
XSLT 1.0 解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"item[@cat = document('file:///c:/temp/DeleteMe/items-to-transform.xml')/*/categorie]">
<xsl:call-template name="identity"/>
<item cat="{@cat}-FR">
<xsl:apply-templates/>
</item>
</xsl:template>
</xsl:stylesheet>
当此转换应用于第一个 XML 文档时:
<items>
<item cat="cat_id1">
<link>link1</link>
<link>link11</link>
</item>
<item cat="cat_id2">
<link>link2</link>
<link>link22</link>
</item>
<item cat="cat_id3">
<link>link3</link>
</item>
</items>
第二个文档位于 C:\tem[\DeleteMe\items-to-transform.xml
的文件中,拼写错误已更正,因此这是一个格式正确的 XML 文档:
<categories>
<categorie>cat_id1</categorie>
<categorie>cat_id3</categorie>
</categories>
产生了想要的、正确的结果:
<items>
<item cat="cat_id1">
<link>link1</link>
<link>link11</link>
</item>
<item cat="cat_id1-FR">
<link>link1</link>
<link>link11</link>
</item>
<item cat="cat_id2">
<link>link2</link>
<link>link22</link>
</item>
<item cat="cat_id3">
<link>link3</link>
</item>
<item cat="cat_id3-FR">
<link>link3</link>
</item>
</items>
我有两个文件;
items.xml : 要转换的文件
<items>
<item cat="cat_id1">
<link>link1</link>
<link>link11</link>
</item>
<item cat="cat_id2">
<link>link2</link>
<link>link22</link>
</item>
<item cat="cat_id3">
<link>link3</link>
</item>
</items>
items_to_transforme.xml :包含要翻译的类别的标识符
<categories>
<categorie>cat_id1</categorie>
<categorie>cat_id3</categorie>
</categories>
我需要通过复制文件 items_to_transforme.xml 中具有 cat 属性值的标签来转换 items.xml,然后更改属性值
想要的结果:
<items>
<item cat="cat_id1">
<link>link1</link>
<link>link11</link>
</item>
<item cat="cat_id1-FR">
<link>link1</link>
<link>link11</link>
</item>
<item cat="cat_id2">
<link>link2</link>
<link>link22</link>
</item>
<item cat="cat_id3">
<link>link3</link>
</item>
<item cat="cat_id3-FR">
<link>link3</link>
</item>
</items>
我如何使用 xslt 执行此操作?我是 xslt 的新手,感谢您的帮助。
为第二个文档中的元素定义一个键,并将其用于您复制匹配元素的模板的匹配模式(例如,通过将处理委托给身份转换设置):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="categories-doc">
<categories>
<categorie>cat_id1</categorie>
<categorie>cat_id3</categorie>
</categories>
</xsl:param>
<xsl:key name="cat-key" match="categorie" use="."/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="item[key('cat-key', @cat, $categories-doc)]">
<xsl:next-match/>
<xsl:apply-templates select="." mode="change-id"/>
</xsl:template>
<xsl:mode name="change-id" on-no-match="shallow-copy"/>
<xsl:template mode="change-id" match="item/@cat">
<xsl:attribute name="{name()}" select=". || '-FR'"/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/gWEamLh/1 内联了第二个文档以确保示例的完整性,但当然可以使用 <xsl:param name="categories-doc" select="doc('categories.xml')"/>
。示例还使用 XSLT 3,身份转换是使用 xsl:mode
声明设置的,但当然对于 XSLT 2,您可以将其拼写为模板。
XSLT 1.0 解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"item[@cat = document('file:///c:/temp/DeleteMe/items-to-transform.xml')/*/categorie]">
<xsl:call-template name="identity"/>
<item cat="{@cat}-FR">
<xsl:apply-templates/>
</item>
</xsl:template>
</xsl:stylesheet>
当此转换应用于第一个 XML 文档时:
<items>
<item cat="cat_id1">
<link>link1</link>
<link>link11</link>
</item>
<item cat="cat_id2">
<link>link2</link>
<link>link22</link>
</item>
<item cat="cat_id3">
<link>link3</link>
</item>
</items>
第二个文档位于 C:\tem[\DeleteMe\items-to-transform.xml
的文件中,拼写错误已更正,因此这是一个格式正确的 XML 文档:
<categories>
<categorie>cat_id1</categorie>
<categorie>cat_id3</categorie>
</categories>
产生了想要的、正确的结果:
<items>
<item cat="cat_id1">
<link>link1</link>
<link>link11</link>
</item>
<item cat="cat_id1-FR">
<link>link1</link>
<link>link11</link>
</item>
<item cat="cat_id2">
<link>link2</link>
<link>link22</link>
</item>
<item cat="cat_id3">
<link>link3</link>
</item>
<item cat="cat_id3-FR">
<link>link3</link>
</item>
</items>