XSLT 1.0 - 根据来自不同节点的属性值创建节点
XSLT 1.0 - Creating nodes based on attribute values from different nodes
我很难处理以下用例。
这里是 XML:
<NodeA>
<NodeB>
<Application id="I-555" name="Text1" XorY="Y" />
<Application id="I-666" name="Text2" XorY="X" />
<Application id="I-777" name="Text3" XorY="Y" />
<Application id="I-888" name="Text4" XorY="X" />
</NodeB>
</NodeA>
<NodeD>
<NodeE>
<Process id="111" name="Text1" />
<Process id="222" name="Text2" />
<Process id="333" name="Text2" />
<Process id="444" name="Text2" />
</NodeE>
</NodeD>
<Links_between_Process_and_Application>
<Link_Process_App app_id="I-555" process_id="111" />
<Link_Process_App app_id="I-666" process_id="222" />
<Link_Process_App app_id="I-777" process_id="333" />
<Link_Process_App app_id="I-888" process_id="444" />
</Links_between_Process_and_Application>
我想要实现的是 create/tranform 一个新的 XML,在节点“Application”和“Process”之间,基于节点 <Links_between_Process_and_Application>
,带有两个新链接.
棘手的部分是(至少对我而言)是根据 XorY
(伪代码)的属性值创建两个不同的 links/nodes:
同时遍历(for-each)<Links_between_Process_and_Application>
IF(检查当前 app_id(例如 I-555)如果 @XorY='X' 在节点“Application”中)
创建 <Link_Process_Application>
ELSE IF(检查节点“应用程序”中的当前 app_id(例如 I-555)if @XorY='Y'
创建 <Link_Process_IDP>
我已经为转换和生成这两个链接编写了两个 XSLT(没有检查属性 XorY),因为对于这个用例,我真的不知道如何检查不同属性的值:
<?xml version='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:template match="/">
<ImportSchemaBase>
<xsl:for-each select="Links_between_Process_and_Application/Link_Process_App">
<Link_Process_Application>
<SourceKey>
<xsl:value-of select="@process_id"/>
</SourceKey>
<TargetKey>
<xsl:value-of select="@app_id"/>
</TargetKey>
</Link_Process_Application>
</xsl:for-each>
</ImportSchemaBase>
</xsl:template>
</xsl:stylesheet>
和:
<?xml version='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:template match="/">
<ImportSchemaBase>
<xsl:for-each select="Links_between_Process_and_Application/Link_Process_App">
<Link_Process_IDP>
<SourceKey>
<xsl:value-of select="@process_id"/>
</SourceKey>
<TargetKey>
<xsl:value-of select="@app_id"/>
</TargetKey>
</Link_Process_IDP>
</xsl:for-each>
</ImportSchemaBase>
</xsl:template>
</xsl:stylesheet>
结果应该是:
创建 Link_Process_IDP 因为对于“app_id=I-555” XorY 是 Y
<Link_Process_IDP>
<SourceKey>111</SourceKey>
<TargetKey>I-555</TargetKey>
</Link_Process_IDP>
创建 Link_Process_Application 因为对于“app_id=I-666” XorY 是 X
<Link_Process_Application>
<SourceKey>222</SourceKey>
<TargetKey>I-666</TargetKey>
</Link_Process_Application>
创建 Link_Process_IDP 因为对于“app_id=I-777” XorY 是 Y
<Link_Process_IDP>
<SourceKey>333</SourceKey>
<TargetKey>I-777</TargetKey>
</Link_Process_IDP>
创建 Link_Process_Application 因为对于“app_id=I-888” XorY 是 X
<Link_Process_Application>
<SourceKey>444</SourceKey>
<TargetKey>I-888</TargetKey>
</Link_Process_Application>
非常感谢您,抱歉您的描述太长了!
我会这样做:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="app" match="Application" use="@id"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="//Link_Process_App"/>
</xsl:template>
<xsl:template match="Link_Process_App[key('app', @app_id)/@XorY = 'X']">
<Link_Process_Application>
<SourceKey>
<xsl:value-of select="@process_id"/>
</SourceKey>
<TargetKey>
<xsl:value-of select="@app_id"/>
</TargetKey>
</Link_Process_Application>
</xsl:template>
<xsl:template match="Link_Process_App[key('app', @app_id)/@XorY = 'Y']">
<Link_Process_IDP>
<SourceKey>
<xsl:value-of select="@process_id"/>
</SourceKey>
<TargetKey>
<xsl:value-of select="@app_id"/>
</TargetKey>
</Link_Process_IDP>
</xsl:template>
</xsl:stylesheet>
您的输入不是 XML - 它缺少单个根元素(您的预期输出也是如此)。
给定格式良好的 XML 输入,使用 key:
很容易完成任务
XML
<root>
<NodeA>
<NodeB>
<Application id="I-555" name="Text1" XorY="Y" />
<Application id="I-666" name="Text2" XorY="X" />
<Application id="I-777" name="Text3" XorY="Y" />
<Application id="I-888" name="Text4" XorY="X" />
</NodeB>
</NodeA>
<NodeD>
<NodeE>
<Process id="111" name="Text1" />
<Process id="222" name="Text2" />
<Process id="333" name="Text2" />
<Process id="444" name="Text2" />
</NodeE>
</NodeD>
<Links_between_Process_and_Application>
<Link_Process_App app_id="I-555" process_id="111" />
<Link_Process_App app_id="I-666" process_id="222" />
<Link_Process_App app_id="I-777" process_id="333" />
<Link_Process_App app_id="I-888" process_id="444" />
</Links_between_Process_and_Application>
</root>
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:key name="app" match="Application" use="@id" />
<xsl:template match="/root">
<output>
<xsl:for-each select="Links_between_Process_and_Application/Link_Process_App">
<xsl:variable name="xory" select="key('app', @app_id)/@XorY" />
<xsl:variable name="name">
<xsl:choose>
<xsl:when test="$xory = 'X'">Link_Process_Application</xsl:when>
<xsl:when test="$xory = 'Y'">Link_Process_IDP</xsl:when>
<xsl:otherwise>SomethingElse</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$name}">
<SourceKey>
<xsl:value-of select="@process_id"/>
</SourceKey>
<TargetKey>
<xsl:value-of select="@app_id"/>
</TargetKey>
</xsl:element>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="UTF-8"?>
<output>
<Link_Process_IDP>
<SourceKey>111</SourceKey>
<TargetKey>I-555</TargetKey>
</Link_Process_IDP>
<Link_Process_Application>
<SourceKey>222</SourceKey>
<TargetKey>I-666</TargetKey>
</Link_Process_Application>
<Link_Process_IDP>
<SourceKey>333</SourceKey>
<TargetKey>I-777</TargetKey>
</Link_Process_IDP>
<Link_Process_Application>
<SourceKey>444</SourceKey>
<TargetKey>I-888</TargetKey>
</Link_Process_Application>
</output>
请注意,如果 X
和 Y
互斥,您可以将其进一步缩短为:
<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:key name="app" match="Application" use="@id" />
<xsl:template match="/root">
<output>
<xsl:for-each select="Links_between_Process_and_Application/Link_Process_App">
<xsl:variable name="name">
<xsl:choose>
<xsl:when test="key('app', @app_id)/@XorY = 'X'">Link_Process_Application</xsl:when>
<xsl:otherwise>Link_Process_IDP</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$name}">
<SourceKey>
<xsl:value-of select="@process_id"/>
</SourceKey>
<TargetKey>
<xsl:value-of select="@app_id"/>
</TargetKey>
</xsl:element>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
我很难处理以下用例。
这里是 XML:
<NodeA>
<NodeB>
<Application id="I-555" name="Text1" XorY="Y" />
<Application id="I-666" name="Text2" XorY="X" />
<Application id="I-777" name="Text3" XorY="Y" />
<Application id="I-888" name="Text4" XorY="X" />
</NodeB>
</NodeA>
<NodeD>
<NodeE>
<Process id="111" name="Text1" />
<Process id="222" name="Text2" />
<Process id="333" name="Text2" />
<Process id="444" name="Text2" />
</NodeE>
</NodeD>
<Links_between_Process_and_Application>
<Link_Process_App app_id="I-555" process_id="111" />
<Link_Process_App app_id="I-666" process_id="222" />
<Link_Process_App app_id="I-777" process_id="333" />
<Link_Process_App app_id="I-888" process_id="444" />
</Links_between_Process_and_Application>
我想要实现的是 create/tranform 一个新的 XML,在节点“Application”和“Process”之间,基于节点 <Links_between_Process_and_Application>
,带有两个新链接.
棘手的部分是(至少对我而言)是根据 XorY
(伪代码)的属性值创建两个不同的 links/nodes:
同时遍历(for-each)<Links_between_Process_and_Application>
IF(检查当前 app_id(例如 I-555)如果 @XorY='X' 在节点“Application”中)
创建 <Link_Process_Application>
ELSE IF(检查节点“应用程序”中的当前 app_id(例如 I-555)if @XorY='Y'
创建 <Link_Process_IDP>
我已经为转换和生成这两个链接编写了两个 XSLT(没有检查属性 XorY),因为对于这个用例,我真的不知道如何检查不同属性的值:
<?xml version='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:template match="/">
<ImportSchemaBase>
<xsl:for-each select="Links_between_Process_and_Application/Link_Process_App">
<Link_Process_Application>
<SourceKey>
<xsl:value-of select="@process_id"/>
</SourceKey>
<TargetKey>
<xsl:value-of select="@app_id"/>
</TargetKey>
</Link_Process_Application>
</xsl:for-each>
</ImportSchemaBase>
</xsl:template>
</xsl:stylesheet>
和:
<?xml version='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:template match="/">
<ImportSchemaBase>
<xsl:for-each select="Links_between_Process_and_Application/Link_Process_App">
<Link_Process_IDP>
<SourceKey>
<xsl:value-of select="@process_id"/>
</SourceKey>
<TargetKey>
<xsl:value-of select="@app_id"/>
</TargetKey>
</Link_Process_IDP>
</xsl:for-each>
</ImportSchemaBase>
</xsl:template>
</xsl:stylesheet>
结果应该是:
创建 Link_Process_IDP 因为对于“app_id=I-555” XorY 是 Y
<Link_Process_IDP>
<SourceKey>111</SourceKey>
<TargetKey>I-555</TargetKey>
</Link_Process_IDP>
创建 Link_Process_Application 因为对于“app_id=I-666” XorY 是 X
<Link_Process_Application>
<SourceKey>222</SourceKey>
<TargetKey>I-666</TargetKey>
</Link_Process_Application>
创建 Link_Process_IDP 因为对于“app_id=I-777” XorY 是 Y
<Link_Process_IDP>
<SourceKey>333</SourceKey>
<TargetKey>I-777</TargetKey>
</Link_Process_IDP>
创建 Link_Process_Application 因为对于“app_id=I-888” XorY 是 X
<Link_Process_Application>
<SourceKey>444</SourceKey>
<TargetKey>I-888</TargetKey>
</Link_Process_Application>
非常感谢您,抱歉您的描述太长了!
我会这样做:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="app" match="Application" use="@id"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="//Link_Process_App"/>
</xsl:template>
<xsl:template match="Link_Process_App[key('app', @app_id)/@XorY = 'X']">
<Link_Process_Application>
<SourceKey>
<xsl:value-of select="@process_id"/>
</SourceKey>
<TargetKey>
<xsl:value-of select="@app_id"/>
</TargetKey>
</Link_Process_Application>
</xsl:template>
<xsl:template match="Link_Process_App[key('app', @app_id)/@XorY = 'Y']">
<Link_Process_IDP>
<SourceKey>
<xsl:value-of select="@process_id"/>
</SourceKey>
<TargetKey>
<xsl:value-of select="@app_id"/>
</TargetKey>
</Link_Process_IDP>
</xsl:template>
</xsl:stylesheet>
您的输入不是 XML - 它缺少单个根元素(您的预期输出也是如此)。
给定格式良好的 XML 输入,使用 key:
很容易完成任务XML
<root>
<NodeA>
<NodeB>
<Application id="I-555" name="Text1" XorY="Y" />
<Application id="I-666" name="Text2" XorY="X" />
<Application id="I-777" name="Text3" XorY="Y" />
<Application id="I-888" name="Text4" XorY="X" />
</NodeB>
</NodeA>
<NodeD>
<NodeE>
<Process id="111" name="Text1" />
<Process id="222" name="Text2" />
<Process id="333" name="Text2" />
<Process id="444" name="Text2" />
</NodeE>
</NodeD>
<Links_between_Process_and_Application>
<Link_Process_App app_id="I-555" process_id="111" />
<Link_Process_App app_id="I-666" process_id="222" />
<Link_Process_App app_id="I-777" process_id="333" />
<Link_Process_App app_id="I-888" process_id="444" />
</Links_between_Process_and_Application>
</root>
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:key name="app" match="Application" use="@id" />
<xsl:template match="/root">
<output>
<xsl:for-each select="Links_between_Process_and_Application/Link_Process_App">
<xsl:variable name="xory" select="key('app', @app_id)/@XorY" />
<xsl:variable name="name">
<xsl:choose>
<xsl:when test="$xory = 'X'">Link_Process_Application</xsl:when>
<xsl:when test="$xory = 'Y'">Link_Process_IDP</xsl:when>
<xsl:otherwise>SomethingElse</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$name}">
<SourceKey>
<xsl:value-of select="@process_id"/>
</SourceKey>
<TargetKey>
<xsl:value-of select="@app_id"/>
</TargetKey>
</xsl:element>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="UTF-8"?>
<output>
<Link_Process_IDP>
<SourceKey>111</SourceKey>
<TargetKey>I-555</TargetKey>
</Link_Process_IDP>
<Link_Process_Application>
<SourceKey>222</SourceKey>
<TargetKey>I-666</TargetKey>
</Link_Process_Application>
<Link_Process_IDP>
<SourceKey>333</SourceKey>
<TargetKey>I-777</TargetKey>
</Link_Process_IDP>
<Link_Process_Application>
<SourceKey>444</SourceKey>
<TargetKey>I-888</TargetKey>
</Link_Process_Application>
</output>
请注意,如果 X
和 Y
互斥,您可以将其进一步缩短为:
<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:key name="app" match="Application" use="@id" />
<xsl:template match="/root">
<output>
<xsl:for-each select="Links_between_Process_and_Application/Link_Process_App">
<xsl:variable name="name">
<xsl:choose>
<xsl:when test="key('app', @app_id)/@XorY = 'X'">Link_Process_Application</xsl:when>
<xsl:otherwise>Link_Process_IDP</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$name}">
<SourceKey>
<xsl:value-of select="@process_id"/>
</SourceKey>
<TargetKey>
<xsl:value-of select="@app_id"/>
</TargetKey>
</xsl:element>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>