[英]Move/Copy node to multiple child nodes with XSLT
I'm completely new to XSLT and need some help to solve one of my issues. 我是XSLT的新手,需要一些帮助来解决我的问题之一。 What I want to accomplish is this:
我要完成的是:
I have a file looking something like this: 我有一个看起来像这样的文件:
<Transaction>
<Date>2010-10-14T12:06:12.164+01:00</Date>
<Production>NO</Production>
<Document fun:OID="1.9.101106">
<DocumentType xmlns="">Monthly A</DocumentType>
<RangeName xmlns="">Range Name</RangeName>
<Name xmlns="">Equity</Name>
<Language xmlns="">English</Language>
<Class xmlns="">A Acc</Class>
<Active xmlns="">YES</Active>
<Country xmlns="">UK</Country>
<Country xmlns="">Luxembourg</Country>
<Country xmlns="">Denmark</Country>
<Country xmlns="">Malta</Country>
<Primary fun1:OID="1.9.101106" xmlns="" xmlns:fun1="DocumentXML.com">
<Name>SISF-Indian-Equity-A-Acc-FMR-UKEN</Name>
<FileSizeInKB>176784</FileSizeInKB>
<FileType>pdf</FileType>
<ReportingPeriod>September</ReportingPeriod>
<ReportingYear>2010</ReportingYear>
</Primary>
<Primary fun1:OID="1.9.101118" xmlns="" xmlns:fun1="DocumentXML.com">
<Name>SISF-Indian-Equity-A-Acc</Name>
<FileSizeInKB>176784</FileSizeInKB>
<FileType>pdf</FileType>
<ReportingPeriod>September</ReportingPeriod>
<ReportingYear>2010</ReportingYear>
</Primary>
</Document>
</Transaction>
And I want to keep the current file, except that I want to copy the country nodes in to be in the Primary node. 我想保留当前文件,除了要复制国家(地区)节点到“主要”节点中。 So it would look something like this:
所以看起来像这样:
<Transaction>
<Date>2010-10-14T12:06:12.164+01:00</Date>
<Production>NO</Production>
<Document fun:OID="1.9.101106">
<DocumentType xmlns="">Monthly A</DocumentType>
<RangeName xmlns="">Range Name</RangeName>
<Name xmlns="">Equity</Name>
<Language xmlns="">English</Language>
<Class xmlns="">A Acc</Class>
<Active xmlns="">YES</Active>
<Country xmlns="">UK</Country>
<Country xmlns="">Luxembourg</Country>
<Country xmlns="">Denmark</Country>
<Country xmlns="">Malta</Country>
<Primary fun1:OID="1.9.101106" xmlns="" xmlns:fun1="DocumentXML.com">
<Name>SISF-Indian-Equity-A-Acc-FMR-UKEN</Name>
<FileSizeInKB>176784</FileSizeInKB>
<FileType>pdf</FileType>
<ReportingPeriod>September</ReportingPeriod>
<ReportingYear>2010</ReportingYear>
<Country xmlns="">UK</Country>
<Country xmlns="">Luxembourg</Country>
<Country xmlns="">Denmark</Country>
<Country xmlns="">Malta</Country>
</Primary>
<Primary fun1:OID="1.9.101118" xmlns="" xmlns:fun1="DocumentXML.com">
<Name>SISF-Indian-Equity-A-Acc</Name>
<FileSizeInKB>176784</FileSizeInKB>
<FileType>pdf</FileType>
<ReportingPeriod>September</ReportingPeriod>
<ReportingYear>2010</ReportingYear>
<Country xmlns="">UK</Country>
<Country xmlns="">Luxembourg</Country>
<Country xmlns="">Denmark</Country>
<Country xmlns="">Malta</Country>
</Primary>
</Document>
</Transaction>
What would the best approach be to accomplish that? 最好的方法是实现这一目标? Do I need to do a copy of the whole document first and then copy the individual countries, or can I do this in one go somehow?
我需要先制作整个文档的副本,然后再复制各个国家/地区,还是可以一次性完成?
The trick is to use an identity template to copy the whole document but still be able to modify the parts you want: 诀窍是使用身份模板复制整个文档,但仍然能够修改所需的部分:
With this (slightly modified) input: 使用此(略作修改)输入:
<?xml version="1.0" encoding="UTF-8"?>
<Transaction xmlns:fun1="DocumentXML.com">
<Date>2010-10-14T12:06:12.164+01:00</Date>
<Production>NO</Production>
<Document fun1:OID="1.9.101106">
<DocumentType xmlns="">Monthly A</DocumentType>
<RangeName xmlns="">Range Name</RangeName>
<Name xmlns="">Equity</Name>
<Language xmlns="">English</Language>
<Class xmlns="">A Acc</Class>
<Active xmlns="">YES</Active>
<Country xmlns="">UK</Country>
<Country xmlns="">Luxembourg</Country>
<Country xmlns="">Denmark</Country>
<Country xmlns="">Malta</Country>
<Primary fun1:OID="1.9.101106" xmlns="" xmlns:fun1="DocumentXML.com">
<Name>SISF-Indian-Equity-A-Acc-FMR-UKEN</Name>
<FileSizeInKB>176784</FileSizeInKB>
<FileType>pdf</FileType>
<ReportingPeriod>September</ReportingPeriod>
<ReportingYear>2010</ReportingYear>
</Primary>
<Primary fun1:OID="1.9.101118" xmlns="" xmlns:fun1="DocumentXML.com">
<Name>SISF-Indian-Equity-A-Acc</Name>
<FileSizeInKB>176784</FileSizeInKB>
<FileType>pdf</FileType>
<ReportingPeriod>September</ReportingPeriod>
<ReportingYear>2010</ReportingYear>
</Primary>
</Document>
</Transaction>
Explanation for the changes in input XML: The supplied input XML isn't valid because you use double quotes for every attribute. 输入XML更改的说明:提供的输入XML无效,因为您对每个属性都使用了双引号。 Also, the
fun
prefix isn't declared for the Document
node. 另外,未为
Document
节点声明fun
前缀。 I've changed the fun
prefix to fun1
and bound the prefix at root level. 我已将
fun
前缀更改为fun1
并在根级别绑定了该前缀。
And this stylesheet: 这个样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<!-- This identity template copies the document -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<!-- This template will only match the 'Primary' nodes
and modify them the way you want. -->
<xsl:template match="Primary">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
<!-- As you can see, this is the only difference
between the identity template and this specific
template. -->
<xsl:copy-of select="../Country"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Will give you an identical document but with Country
copied into Primary
: 将给您相同的文件,但将
Country
复制到Primary
:
<?xml version="1.0" encoding="UTF-8"?>
<Transaction xmlns:fun1="DocumentXML.com">
<Date>2010-10-14T12:06:12.164+01:00</Date>
<Production>NO</Production>
<Document fun1:OID="1.9.101106">
<DocumentType>Monthly A</DocumentType>
<RangeName>Range Name</RangeName>
<Name>Equity</Name>
<Language>English</Language>
<Class>A Acc</Class>
<Active>YES</Active>
<Country>UK</Country>
<Country>Luxembourg</Country>
<Country>Denmark</Country>
<Country>Malta</Country>
<Primary fun1:OID="1.9.101106">
<Name>SISF-Indian-Equity-A-Acc-FMR-UKEN</Name>
<FileSizeInKB>176784</FileSizeInKB>
<FileType>pdf</FileType>
<ReportingPeriod>September</ReportingPeriod>
<ReportingYear>2010</ReportingYear>
<Country>UK</Country>
<Country>Luxembourg</Country>
<Country>Denmark</Country>
<Country>Malta</Country>
</Primary>
<Primary fun1:OID="1.9.101118">
<Name>SISF-Indian-Equity-A-Acc</Name>
<FileSizeInKB>176784</FileSizeInKB>
<FileType>pdf</FileType>
<ReportingPeriod>September</ReportingPeriod>
<ReportingYear>2010</ReportingYear>
<Country>UK</Country>
<Country>Luxembourg</Country>
<Country>Denmark</Country>
<Country>Malta</Country>
</Primary>
</Document>
</Transaction>
Just for fun, the shortest stylesheet: 只是为了好玩,最短的样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<xsl:apply-templates select="self::Primary/../Country"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Other shorter without changing the identity rule: 其他较短但未更改身份规则:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Primary/*[last()]">
<xsl:call-template name="identity"/>
<xsl:apply-templates select="../../Country"/>
</xsl:template>
</xsl:stylesheet>
Note : Both don't use xsl:copy-of
but xsl:apply-templates
. 注意 :两者都不使用
xsl:copy-of
但是使用xsl:apply-templates
。 This allows further processing. 这允许进一步处理。
well if you are using xslt to generate a new xml doccument i would just create the doccument then for the primary node do this 好吧,如果您使用xslt生成一个新的xml文档,我将只创建该文档,然后为主节点执行此操作
<xsl:for-each select="../Country">
<Country><xsl:value-of select="."/></Country>
</xsl:for-each>
there may be simpler ways to achieve the same results..? 可能会有更简单的方法来达到相同的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.