英文:
XSLT mapping to add missing child tags in the same sequence
问题
以下是翻译好的内容:
<emailClick>
<id>1</id>
<url>https://www.google.com</url>
<email_template_id>12</email_template_id>
<created_at>2023-02-14 00:00:10</created_at>
</emailClick>
<emailClick>
<id>2</id>
<url>https://www.hello.com</url>
<email_template_id/>
<created_at>2023-02-14 00:00:10</created_at>
</emailClick>
关于你的问题,你已经使用XSLT来实现你的目标,这是一个合理的方法。在你的XSLT样式表中,你遍历了rsp/result/emailClick
元素,并为每个元素生成输出。在此过程中,你设置了<email_template_id>
元素的值,但如果没有该元素,你生成了<email_template_id/>
,这是一个有效的处理方式。
你的XSLT代码在这种情况下似乎已经实现了你的需求,没有明显的问题。如果你的XML结构和要求更加复杂,可能需要进一步优化和改进,但根据你提供的信息,它似乎已经有效了。
英文:
I have the below input xml where some mandatory xml tags are missing like <email_template_id>
which needs to be reproduced in the output in the same sequence
<?xml version="1.0" encoding="UTF-8"?>
<rsp stat="ok" version="1.0">
<result>
<total_results>700</total_results>
<emailClick>
<id>1</id>
<url>https://www.google.com</url>
<email_template_id>12</email_template_id>
<created_at>2023-02-14 00:00:10</created_at>
</emailClick>
<emailClick>
<id>2</id>
<url>https://www.hello.com</url>
<created_at>2023-02-14 00:00:10</created_at>
</emailClick>
</result>
</rsp>
and need the below output
<emailClick>
<id>1</id>
<url>https://www.google.com</url>
<email_template_id>12</email_template_id>
<created_at>2023-02-14 00:00:10</created_at>
</emailClick>
<emailClick>
<id>2</id>
<url>https://www.hello.com</url>
<email_template_id/>
<created_at>2023-02-14 00:00:10</created_at>
</emailClick>
I am using below xslt to achieve this output
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" indent ="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:for-each select="rsp/result/emailClick">
<emailClick>
<id><xsl:value-of select="id" /></id>
<url><xsl:value-of select="url" /></url>
<email_template_id><xsl:value-of select="email_template_id"/></email_template_id>
<created_at><xsl:value-of select="created_at"/></created_at>
</emailClick>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Is there any better way to achieve this , any guidance would be highly appreciated
答案1
得分: 0
以下样式表避免在xsl:for-each
内提及元素名称,并从<so:emailClick>
元素中读取必需的元素名称,以通用方式处理它们:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:so="https://stackoverflow.com">
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<so:emailClick>
<id />
<url />
<email_template_id />
<created_at />
</so:emailClick>
<xsl:template match="/">
<xsl:for-each select="rsp/result/emailClick">
<xsl:variable name="this" select="." />
<xsl:copy>
<xsl:for-each select="document('')/*/so:*[local-name()=name(current())]/*">
<xsl:element name="{name()}">
<xsl:value-of select="$this/*[name()=name(current())]" />
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这是否符合你所说的“通用的方法”?
(XSLT 1.0)
英文:
The following stylesheet avoids any mention of element names inside the xsl:for-each
and instead reads the mandatory element names from the <so:emailClick>
element and processes them generically:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:so="https://stackoverflow.com">
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<so:emailClick>
<id />
<url />
<email_template_id />
<created_at />
</so:emailClick>
<xsl:template match="/">
<xsl:for-each select="rsp/result/emailClick">
<xsl:variable name="this" select="." />
<xsl:copy>
<xsl:for-each select="document('')/*/so:*[local-name()=name(current())]/*">
<xsl:element name="{name()}">
<xsl:value-of select="$this/*[name()=name(current())]" />
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Is that what you meant by "a generic way of doing this"?
(XSLT 1.0)
答案2
得分: 0
这是一种推送式编程方法。这意味着它使用apply-templates
来推送子节点。它还使用了一个模式(mode)。因此,输出的节点被推送到一个身份模板。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()">
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="emailClick">
<xsl:copy>
<xsl:apply-templates select="@*" mode="output"/>
<xsl:choose>
<xsl:when test="id">
<xsl:apply-templates select="id" mode="output"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="id"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="url">
<xsl:apply-templates select="url" mode="output"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="url"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="email_template_id">
<xsl:apply-templates select="email_template_id" mode="output"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="email_template_id"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="created_at">
<xsl:apply-templates select="created_at" mode="output"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="created_at"/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
<!-- 身份模板。 -->
<xsl:template match="node()|@*" mode="output">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="output"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
英文:
This is a push programming approach. Which means it pushes the child nodes using apply-templates. It also uses a mode. So the nodes being output are pushed to an identity template.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" indent ="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()">
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="emailClick">
<xsl:copy>
<xsl:apply-templates select="@*" mode="output"/>
<xsl:choose>
<xsl:when test="id">
<xsl:apply-templates select="id" mode="output"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="id"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="url">
<xsl:apply-templates select="url" mode="output"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="url"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="email_template_id">
<xsl:apply-templates select="email_template_id" mode="output"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="email_template_id"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="created_at">
<xsl:apply-templates select="created_at" mode="output"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="created_at"/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
<!-- Identity. -->
<xsl:template match="node()|@*" mode="output">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="output"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论