这实际上是我之前的问题的后续问题,但我已经迭代了我的问题,所以这可能更容易解决。我有以下格式的XML数据:
<v1:publications xmlns:commons="v3.commons.pure.atira.dk"
xmlns:v1="v1.publication-import.base-uk.pure.atira.dk">
<v1:book id="1" subType="book">
<v1:peerReviewed>true</v1:peerReviewed>
<v1:publicationCategory>scientific</v1:publicationCategory>
<v1:publicationStatus>published</v1:publicationStatus>
<v1:language>fi</v1:language>
<v1:title>
<commons:text>Introduction to scientific reduction</commons:text>
</v1:title>
<v1:abstract/>
<v1:persons>
<v1:author>
<v1:role>author</v1:role>
<v1:person>
<v1:firstName>Jane</v1:firstName>
<v1:lastName>Smith</v1:lastName>
</v1:person>
</v1:author>
</v1:persons>
<v1:organisations>
<v1:organisation id="2250500"/>
</v1:organisations>
<v1:owner id="2250500"/>
<v1:publicationDate>
<commons:year>2013</commons:year>
</v1:publicationDate>
<v1:visibility>Public</v1:visibility>
<v1:numberOfPages>2</v1:numberOfPages>
</v1:book>
<v1:book id="1" subType="book">
<v1:persons>
<v1:author>
<v1:role>author</v1:role>
<v1:person>
<v1:firstName>John</v1:firstName>
<v1:lastName>Doe</v1:lastName>
</v1:person>
</v1:author>
</v1:persons>
<v1:organisations>
<v1:organisation id="220300"/>
</v1:organisations>
</v1:book>
</publications>
我到目前为止的XSLT是这样的:
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:commons="v3.commons.pure.atira.dk"
xmlns:v1="v1.publication-import.base-uk.pure.atira.dk"
exclude-result-prefixes="xsi xs"
version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<v1:publications>
<xsl:for-each-group select="/v1:publications/v1:book" group-by="@id">
<xsl:for-each-group select="current-group()" group-by="if(@Key) then @Key else 'no key'">
<v1:book>
<!-- Copy attributes off the *first* GroupData element in the group -->
<xsl:copy-of select="current-group()[1]/@*"/>
<!-- Copy ItemData children from *all* GroupData elements in the group -->
<xsl:copy-of select="current-group()/*" />
</v1:book>
</xsl:for-each-group>
</xsl:for-each-group>
</v1:publications>
问题是,当我想像这样组合它们时,它会在<v1:book>
下为重复项(v1:人)创建单独的节点:
<v1:persons>
<v1:author></v1:author>
<v1:author></v1:author>
</v1:persons>
像<v1:title/>
这样的字段我可以事先从XML中轻松删除,因此它们不是问题。
所需的输出应如下所示,我编辑了几个字段(组织ID和所有者ID以更正)。这是正确导入的实际数据。
<?xml version="1.0" encoding="UTF-8"?>
<v1:publications xmlns:commons="v3.commons.pure.atira.dk"
xmlns:v1="v1.publication-import.base-uk.pure.atira.dk">
<v1:book id="1" subType="book">
<v1:peerReviewed>true</v1:peerReviewed>
<v1:publicationCategory>scientific</v1:publicationCategory>
<v1:publicationStatus>published</v1:publicationStatus>
<v1:language>fi_FI</v1:language>
<v1:title>
<commons:text>Introduction to scientific reduction</commons:text>
</v1:title>
<v1:persons>
<v1:author>
<v1:role>author</v1:role>
<v1:person>
<v1:firstName>Jane</v1:firstName>
<v1:lastName>Smith</v1:lastName>
</v1:person>
</v1:author>
<v1:author>
<v1:role>author</v1:role>
<v1:person>
<v1:firstName>John</v1:firstName>
<v1:lastName>Die</v1:lastName>
</v1:person>
</v1:author>
</v1:persons>
<v1:organisations>
<v1:organisation id="2250500"/>
<v1:organisation id="2250300"/>
</v1:organisations>
<v1:owner id="2250300"/>
<v1:publicationDate>
<commons:year>2013</commons:year>
</v1:publicationDate>
<v1:visibility>Public</v1:visibility>
<v1:numberOfPages>2</v1:numberOfPages>
</v1:book>
</v1:publications>
答案 0 :(得分:0)
假设所需的输出是
<v1:persons>
<v1:author>
<v1:fullName>John Doe</v1:fullName>
</v1:author>
</v1:persons>
你需要替换<xsl:copy-of>
,它使用每个项目的副本模板来制作完美的副本(因此不允许在其中进行更改)。
一般身份模板match="@*|node()
将匹配所有内容(请参阅https://stackoverflow.com/a/617611/2564301),但这将由match="v1:author"
的特定模板覆盖。这只是写出<v1:firstName>
和<v1:lastName>
的值,中间只有一个空格。
为了保持一致性,我添加了<xsl:copy>
来复制<v1:author>
标记本身,再加上<xsl:apply-templates select="@*"/>
来复制其所有属性。这样它也可以使用
<v1:author id='1'>
- 该属性将按预期复制。
<xsl:template match="/">
<v1:publications>
<xsl:for-each-group select="/v1:publications/v1:book" group-by="@id">
<xsl:for-each-group select="current-group()" group-by="if(@Key) then @Key else 'no key'">
<v1:book>
<!-- Copy attributes off the *first* GroupData element in the group -->
<xsl:apply-templates select="current-group()[1]/@*"/>
<!-- Copy ItemData children from *all* GroupData elements in the group -->
<xsl:apply-templates select="current-group()/*" />
</v1:book>
</xsl:for-each-group>
</xsl:for-each-group>
</v1:publications>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="v1:author">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<v1:fullName>
<xsl:value-of select="v1:person/v1:firstName" />
<xsl:text> </xsl:text>
<xsl:value-of select="v1:person/v1:lastName" />
</v1:fullName>
</xsl:copy>
</xsl:template>
这样可以忠实地复制输入,但<v1:persons>
部分替换为
<v1:persons>
<v1:author id="1">
<v1:fullName>Jane Smith</v1:fullName>
</v1:author>
<v1:author id="2">
<v1:fullName>Bob Sandurz</v1:fullName>
</v1:author>
</v1:persons>
(我为测试添加了第二个名称和属性。)
答案 1 :(得分:0)
就像不同的方法一样,只使用相同的id
复制书籍的作者而不连接名字和姓氏 - 遵循XSLT
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:commons="v3.commons.pure.atira.dk"
xmlns:v1="v1.publication-import.base-uk.pure.atira.dk"
exclude-result-prefixes="xsi xs"
version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<v1:publications>
<xsl:for-each-group select="/v1:publications/v1:book" group-by="@id">
<xsl:apply-templates select="."/>
</xsl:for-each-group>
</v1:publications>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="v1:person">
<xsl:variable name="id" select="ancestor::v1:book/@id"/>
<xsl:copy-of select="//v1:person[ancestor::v1:book[@id=$id]]"/>
</xsl:template>
</xsl:stylesheet>
当应用于您的输入时,XML会生成输出(相关部分)
<v1:persons>
<v1:author>
<v1:role>author</v1:role>
<v1:person>
<v1:firstName>Jane</v1:firstName>
<v1:lastName>Smith</v1:lastName>
</v1:person>
<v1:person>
<v1:firstName>John</v1:firstName>
<v1:lastName>Doe</v1:lastName>
</v1:person>
</v1:author>
</v1:persons>
匹配v1:person
的模板会复制具有相同v1:person
的图书子项的所有id
个节点。
保存了Demo,另外还有一本不同的id
第二本书。