我是XSLT的新手,需要一些帮助来解决我的一个问题。我想要完成的是:
我有一个类似这样的文件:
<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>
我想保留当前文件,除了我想要将国家/地区节点复制到主节点中。所以它看起来像这样:
<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>
实现这一目标的最佳方法是什么?我是否需要先复印整份文件,然后复制各个国家,或者我可以一次性完成这项工作吗?
答案 0 :(得分:2)
诀窍是使用identity template复制整个文档,但仍然可以修改所需的部分:
使用此(稍加修改)输入:
<?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>
输入XML更改的说明:提供的输入XML无效,因为您对每个属性都使用双引号。此外,未为fun
节点声明Document
前缀。我已将fun
前缀更改为fun1
并将前缀绑定在根级别。
此样式表:
<?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>
将为您提供相同的文档,但将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>
答案 1 :(得分:1)
只是为了好玩,最短的样式表:
<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>
其他较短而不改变身份规则:
<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>
注意:两者都不使用xsl:copy-of
,而是使用xsl:apply-templates
。这允许进一步处理。
答案 2 :(得分:0)
如果你使用xslt来生成一个新的xml doccument,我会创建一个doccument然后为主节点做这个
<xsl:for-each select="../Country">
<Country><xsl:value-of select="."/></Country>
</xsl:for-each>
可能有更简单的方法来实现相同的结果..?