给定<item>
,我想提取元素的值,将其转换为给定的对应值,并将其作为属性值与第二个元素的值一起插入。
我有以下XML(修剪过多的标签,命名空间等):
<items>
<item>
<title>Test Title</title>
<date>Sun, 26 Feb 2012 08:25:20 +0000</date>
<creator>hsimah</creator>
<description>Test description</description>
<content>Test content here.</content>
<post_id>351</post_id>
<post_name>test-title</post_name>
<status>publish</status>
<post_parent>245</post_parent>
</item>
</items>
我要求它采用以下格式( NB translated_post_parent ):
<Container>
<Data>
<Item Id="{translated_post_parent}/test-title" Status="publish" />
<Route Alias="{translated_post_parent}/test-title" />
<Details Owner="hsimah" />
<Title Title="Test Title" />
</Data>
</Container>
我正在进行的XSLT:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<Container>
<xsl:for-each select ="items/item">
<Data>
<Item Id="{post_name}" Status="{status}">
<Route Alias="{post_name}" />
<Details Owner="{creator}" />
<Title Title="{title}" />
</Data>
</xsl:for-each>
</Container>
</xsl:template>
</xsl:stylesheet>
到目前为止一切顺利。但我现在需要做的是将post_parent
转换为新的相应值。我有一个已翻译的值列表,并编写了一个模板:
<xsl:template match="post_parent/text()[.='245']">
<TestPart Container="NewValue" />
</xsl:template>
将此添加到<Data>
有效负载:
<xsl:apply-templates select="post_parent" />
结果是:
<TestPart Container="NewValue" />
我无法弄清楚如何将该值纳入所需属性(Id
中的<Item>
和Alias
中的<Route>
)以及<post_name>
中的值。简单来说,我需要的是:
<TestPart Container="NewValue/{post_name}" />
其中<post_parent>
为245
(现在为NewValue
)。
答案 0 :(得分:1)
由于post_name
是发布的XML中post_parent
的前导兄弟,因此您可以使用preceding-sibling
轴从当前post_parent
上下文中获取它:
<xsl:template match="post_parent[.='245']">
<TestPart Container="NewValue/{preceding-sibling::post_name}" />
</xsl:template>
或者如果post_name
和post_parent
的外观顺序是任意的,您可以先向上移动一级到父元素,然后再向下移动以获得相应的post_name
:< / p>
<xsl:template match="post_parent[.='245']">
<TestPart Container="NewValue/{parent::*/post_name}" />
</xsl:template>
<强> xsltransform.net demo
强>
另外,您的<xsl:for-each select ="items/item">
可以替换为xsl:apply-templates
以及<xsl:template match="items/item">
。与foreach循环相比,在XSLT中使用模板被认为是更自然的方法。