属性

时间:2016-01-14 10:18:00

标签: xml xslt

给定<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)。

1 个答案:

答案 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_namepost_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中使用模板被认为是更自然的方法。