我有以下xml数据结构要转换:
<root>
<main1>
<page>
<text-body>
<title>K1</title>
<subtitle>Text</subtitle>
</text-body>
<text-body>
<title>Text</title>
<subtitel>Text</subtitel>
</text-body>
<text-body>
<title>Text</title>
<subtitel>Text</subtitel>
</text-body>
</page>
<page>
<text-body>
<title>K2</title>
<subtitel>Text</subtitel>
</text-body>
<text-body>
<title>Text</title>
<subtitel>Text</subtitel>
</text-body>
</page>
<page>
<text-body>
<title>K3</title>
<subtitel>Text</subtitel>
</text-body>
<text-body>
<title>Text</title>
<subtitel>Text</subtitel>
</text-body>
</page>
</main1>
<main2>
<text-body>
<title>B</title>
<subtitle>B</subtitle>
<body>B</body>
</text-body>
<text-body>
<title>C</title>
<subtitle>C</subtitle>
<body>C</body>
</text-body>
<text-body>
<title>D</title>
<subtitle>D</subtitle>
<body>D</body>
</text-body>
</main2>
</root>
我需要将main1 / text-body中的数据替换为标题K1,K2,K3和main2 / text-body中的数据,但是将其他text-body元素保留在main1中。输出应如下所示:
<root>
<main1>
<page>
<text-body>
<title>B</title>
<subtitle>B</subtitle>
<body>B</body>
</text-body>
<text-body>
<title>Text</title>
<subtitel>Text</subtitel>
</text-body>
<text-body>
<title>Text</title>
<subtitel>Text</subtitel>
</text-body>
</page>
<page>
<text-body>
<title>C</title>
<subtitle>C</subtitle>
<body>C</body>
</text-body>
<text-body>
<title>Text</title>
<subtitel>Text</subtitel>
</text-body>
</page>
<page>
<text-body>
<title>D</title>
<subtitle>D</subtitle>
<body>D</body>
</text-body>
<text-body>
<title>Text</title>
<subtitel>Text</subtitel>
</text-body>
</page>
</main1>
<main2>
<text-body>
<title>B</title>
<subtitle>B</subtitle>
<body>B</body>
</text-body>
<text-body>
<title>C</title>
<subtitle>C</subtitle>
<body>C</body>
</text-body>
<text-body>
<title>D</title>
<subtitle>D</subtitle>
<body>D</body>
</text-body>
</main2>
</root>
我有以下xsl代码:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="main1/page/text-body">
<xsl:param name="count" select="title/substring(.,2,1)"/>
<xsl:if test="title/substring(.,1,1)='K'">
<xsl:copy-of select="/root/main2/text-body[$count]"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
我尝试选择标题中的数字,并检查文本中是否有K.但它不起作用。我不知道如何保留其他文本正文元素。这是当前的输出:
<main1>
<page>
<text-body>
<title>B</title>
<subtitle>B</subtitle>
<body>B</body>
</text-body><text-body>
<title>C</title>
<subtitle>C</subtitle>
<body>C</body>
</text-body><text-body>
<title>D</title>
<subtitle>D</subtitle>
<body>D</body>
</text-body>
</page>
<page>
<text-body>
<title>B</title>
<subtitle>B</subtitle>
<body>B</body>
</text-body><text-body>
<title>C</title>
<subtitle>C</subtitle>
<body>C</body>
</text-body><text-body>
<title>D</title>
<subtitle>D</subtitle>
<body>D</body>
</text-body>
</page>
<page>
<text-body>
<title>B</title>
<subtitle>B</subtitle>
<body>B</body>
</text-body><text-body>
<title>C</title>
<subtitle>C</subtitle>
<body>C</body>
</text-body><text-body>
<title>D</title>
<subtitle>D</subtitle>
<body>D</body>
</text-body>
</page>
</main1>
<main2>
<text-body>
<title>B</title>
<subtitle>B</subtitle>
<body>B</body>
</text-body>
<text-body>
<title>C</title>
<subtitle>C</subtitle>
<body>C</body>
</text-body>
<text-body>
<title>D</title>
<subtitle>D</subtitle>
<body>D</body>
</text-body>
</main2>
</root>
请帮忙!
答案 0 :(得分:0)
使用谓词仅匹配您真正想要交换的text-body
元素。在使用XSLT 2.0时,可以在谓词中使用正则表达式:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="main1/page/text-body[matches(title,'^K\d+$')]">
<xsl:variable name="count" select="xs:integer(title/substring(.,2))"/>
<xsl:copy-of select="/root/main2/text-body[$count]"/>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
主要问题是您的 count 参数设置为字符串,但如果您想将in用作索引,则它应该是一个数字,因此您需要执行此操作< / p>
<xsl:copy-of select="/root/main2/text-body[number($count)]"/>
此外,您可能不希望在此使用 xsl:if ,因为使用当前模板时,如果使用if,则不会输出 text-body 元素条件是假的。您实际应该将测试移动到模板匹配的一部分。
<xsl:template match="main1/page/text-body[title/substring(.,1,1)='K']">
这是完整的XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="main1/page/text-body[title/substring(.,1,1)='K']">
<xsl:param name="count" select="title/substring(.,2,1)"/>
<xsl:copy-of select="/root/main2/text-body[number($count)]"/>
</xsl:template>
</xsl:stylesheet>
这应该会产生您的预期输出。
如果您对不同的方法感兴趣,可以选择定义 xsl:key 来查找 main2 / text-body 元素
<xsl:key name="main2"
match="main2/text-body"
use="concat('K', count(preceding-sibling::text-body) + 1)" />
这样,您可以通过使用以下模板来匹配 main1 / page / text-body 元素来删除对子字符串的需求
<xsl:template match="main1/page/text-body[key('main2', title)]">
<xsl:copy-of select="key('main2', title)"/>
</xsl:template>