XML - XSLT - 使用第二个 xml 文档向 xml 文档添加新元素
XML - XSLT - Adding new element to xml document with second xml document
这个问题我已经有一段时间了,我无法解决,所以我决定在这里post,
我有以下简单的 XML 输入文档:
<?xml version="1.0" encoding="UTF-8"?>
<doc1 xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23">
<text-prop name="docName">firstDoc</text-prop>
<body>
<column id="17"/>
<column id="18"/>
<column id="19"/>
</body>
</doc1>
我想添加两个新元素,一个是 <elements>
,里面有 <element>
。然后我还想添加一个 <newColumn>
元素,它是 <body>
元素的子元素。所以我想要得到的结果是:
<?xml version="1.0" encoding="UTF-8"?>
<doc1 xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23">
<text-prop name="docName">firstDoc</text-prop>
<elements>
<element name="first element"/>
</elements>
<body>
<column id="17"/>
<column id="18"/>
<column id="19"/>
<newColumn name="dataSet">first element</newColumn>
</body>
</doc1>
这是我正在使用的 XSLT 样式表,基于@Martin Honnen 在相关 post 中给我的样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xpath-default-namespace="http://www.eclipse.org/birt/2005/design"
xmlns="http://www.eclipse.org/birt/2005/design"
exclude-result-prefixes="xs"
expand-text="yes"
version="3.0">
<xsl:param name="doc2" xmlns="">
<doc2>
<elemList1>
<elem1 ID="001" name="firstDoc" />
<elem1 ID="002" name="secondDoc"/>
</elemList1>
<elemList2>
<elem2 elemID="001">
<elemData name="first element"/>
</elem2>
<elem2 elemID="002">
<elemData name="second element"/>
</elem2>
</elemList2>
</doc2>
</xsl:param>
<xsl:output indent="yes" cdata-section-elements="xml-prop"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:key name="layout-ref" match="elem1" use="@name" xpath-default-namespace=""/>
<xsl:key name="report-ref" match="elem2" use="@elemID" xpath-default-namespace=""/>
<xsl:template match="doc1/text-prop[@name = 'docName']">
<xsl:next-match/>
<xsl:variable name="layout" select="key('layout-ref', ., $doc2)"/>
<xsl:variable name="report" select="key('report-ref', $layout/@ID, $doc2)"/>
<elements>
<xsl:apply-templates select="$report//elemData" xpath-default-namespace=""/>
</elements>
</xsl:template>
<xsl:template match="elemData" xpath-default-namespace="">
<element name="{@name}"/>
</xsl:template>
<!--HERE IT STOPS WORKING-->
<xsl:template match="doc1/body/column[last()]" >
<xsl:next-match/>
<xsl:variable name="layout2" select="key('layout-ref', ., $doc2)"/>
<xsl:variable name="report2" select="key('report-ref', $layout2/@ID, $doc2)"/>
<newColumn name="dataSet">
<xsl:value-of select="$report2/elemData/@name" xpath-default-namespace=""/>
</newColumn>
</xsl:template>
</xsl:stylesheet>
所以我实际得到的结果是这个:
<?xml version="1.0" encoding="UTF-8"?>
<doc1 xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23">
<text-prop name="docName">firstDoc</text-prop>
<elements>
<element name="first element"/>
</elements>
<body>
<column id="17"/>
<column id="18"/>
<column id="19"/>
<newColumn name="dataSet"/>
</body>
</doc1>
基本上我希望元素 <newColumn>
的值与元素 <element>
的属性 name
的值相同,但我无法访问该值并将其放入 <newColumn> element
如您所见,我能够访问相同的值并将其作为新 <element>
元素的属性。
我不能通过这种方式访问我定义为 <xsl:param>
(doc2) 的文档吗?
参见 XSLT FIDDLE AT: https://xsltfiddle.liberty-development.net/3NzcBtf/1
谢谢!
亚历山大·哈辛托
看来我猜对了您在评论中想要的内容,我现在 post 将其作为答案,以便您可以将问题标记为已解决。
当你使用键函数时,你需要传入你想要查找的节点的键值,即在match="doc1/text-prop[@name = 'docName']"
中你传入key('layout-ref', ., $doc2)
这是字符串值(例如 firstDoc
)匹配的 text-prop
元素。在您的 match="doc1/body/column[last()]"
列元素中没有该字符串值(您的列为空),因此从您的问题中不太清楚您希望如何将列与其他元素相关联,除非您想导航到key('layout-ref', ancestor::doc1/text-prop[@name = 'docName'], $doc2)
.
这个问题我已经有一段时间了,我无法解决,所以我决定在这里post,
我有以下简单的 XML 输入文档:
<?xml version="1.0" encoding="UTF-8"?>
<doc1 xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23">
<text-prop name="docName">firstDoc</text-prop>
<body>
<column id="17"/>
<column id="18"/>
<column id="19"/>
</body>
</doc1>
我想添加两个新元素,一个是 <elements>
,里面有 <element>
。然后我还想添加一个 <newColumn>
元素,它是 <body>
元素的子元素。所以我想要得到的结果是:
<?xml version="1.0" encoding="UTF-8"?>
<doc1 xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23">
<text-prop name="docName">firstDoc</text-prop>
<elements>
<element name="first element"/>
</elements>
<body>
<column id="17"/>
<column id="18"/>
<column id="19"/>
<newColumn name="dataSet">first element</newColumn>
</body>
</doc1>
这是我正在使用的 XSLT 样式表,基于@Martin Honnen 在相关 post 中给我的样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xpath-default-namespace="http://www.eclipse.org/birt/2005/design"
xmlns="http://www.eclipse.org/birt/2005/design"
exclude-result-prefixes="xs"
expand-text="yes"
version="3.0">
<xsl:param name="doc2" xmlns="">
<doc2>
<elemList1>
<elem1 ID="001" name="firstDoc" />
<elem1 ID="002" name="secondDoc"/>
</elemList1>
<elemList2>
<elem2 elemID="001">
<elemData name="first element"/>
</elem2>
<elem2 elemID="002">
<elemData name="second element"/>
</elem2>
</elemList2>
</doc2>
</xsl:param>
<xsl:output indent="yes" cdata-section-elements="xml-prop"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:key name="layout-ref" match="elem1" use="@name" xpath-default-namespace=""/>
<xsl:key name="report-ref" match="elem2" use="@elemID" xpath-default-namespace=""/>
<xsl:template match="doc1/text-prop[@name = 'docName']">
<xsl:next-match/>
<xsl:variable name="layout" select="key('layout-ref', ., $doc2)"/>
<xsl:variable name="report" select="key('report-ref', $layout/@ID, $doc2)"/>
<elements>
<xsl:apply-templates select="$report//elemData" xpath-default-namespace=""/>
</elements>
</xsl:template>
<xsl:template match="elemData" xpath-default-namespace="">
<element name="{@name}"/>
</xsl:template>
<!--HERE IT STOPS WORKING-->
<xsl:template match="doc1/body/column[last()]" >
<xsl:next-match/>
<xsl:variable name="layout2" select="key('layout-ref', ., $doc2)"/>
<xsl:variable name="report2" select="key('report-ref', $layout2/@ID, $doc2)"/>
<newColumn name="dataSet">
<xsl:value-of select="$report2/elemData/@name" xpath-default-namespace=""/>
</newColumn>
</xsl:template>
</xsl:stylesheet>
所以我实际得到的结果是这个:
<?xml version="1.0" encoding="UTF-8"?>
<doc1 xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23">
<text-prop name="docName">firstDoc</text-prop>
<elements>
<element name="first element"/>
</elements>
<body>
<column id="17"/>
<column id="18"/>
<column id="19"/>
<newColumn name="dataSet"/>
</body>
</doc1>
基本上我希望元素 <newColumn>
的值与元素 <element>
的属性 name
的值相同,但我无法访问该值并将其放入 <newColumn> element
如您所见,我能够访问相同的值并将其作为新 <element>
元素的属性。
我不能通过这种方式访问我定义为 <xsl:param>
(doc2) 的文档吗?
参见 XSLT FIDDLE AT: https://xsltfiddle.liberty-development.net/3NzcBtf/1
谢谢!
亚历山大·哈辛托
看来我猜对了您在评论中想要的内容,我现在 post 将其作为答案,以便您可以将问题标记为已解决。
当你使用键函数时,你需要传入你想要查找的节点的键值,即在match="doc1/text-prop[@name = 'docName']"
中你传入key('layout-ref', ., $doc2)
这是字符串值(例如 firstDoc
)匹配的 text-prop
元素。在您的 match="doc1/body/column[last()]"
列元素中没有该字符串值(您的列为空),因此从您的问题中不太清楚您希望如何将列与其他元素相关联,除非您想导航到key('layout-ref', ancestor::doc1/text-prop[@name = 'docName'], $doc2)
.