1

我是 xslt 的新手,所以如果这是一个幼稚的问题,请原谅。我需要将源文档中包含部门名称的元素的值与另一个文档中的子元素的值匹配,该文档将部门名称的变体列为子元素,并将该子元素的父节点设置为当前节点以获取值的其他孩子。

以下是源文档的示例:

<sourceRoot>
 <sourceElement>foo</sourceElement>
</sourceRoot>

这是列表文档的示例:

<departments>
 <department>
  <child1>bar</child1>
  <child2>bar2</child2>
  <child3>bar3</child3>
 </department>
 <department>
  <child1>baz</child1>
  <child2>baz2</child2>
  <child3>baz3</child3>
 </department>
 <department>
  <child1>foo</child1>
  <child2>foo2</child2>
  <child3>foo3</child3>
 </department>
</departments>
etc.

这是期望的结果:

<child2value>foo2</child2value>
<child3value>foo3</child3value>

我曾尝试使用此 xsl:

<?xml version="1.0" encoding="UTF-8"?>
<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" indent="yes" omit-xml-declaration="no" encoding="UTF-8"/>
    <xsl:preserve-space elements="text"/>

    <xsl:variable name="departments" select="document('dept.xml')/departments"/>  

    <xsl:template match="/">          
        <xsl:variable name="sourceElement" select="sourceRoot/sourceElement"/>                   
        <xsl:variable name="child1" select="$departments/department/child1"/> 
        <xsl:variable name="child2" select="$departments/department/child2"/>
        <xsl:variable name="child3" select="$departments/department/child3"/>

        <xsl:choose>    
        <xsl:when test="$sourceElement=$child1">               
            <child2value>
                <xsl:value-of select="$departments/department[.]/child2"/>
            </child2value>
            <child3value>
                <xsl:value-of select="$departments/department[.]/child3"/>                
            </child3value>
        </xsl:when>
        <xsl:otherwise/>
    </xsl:choose>   
    </xsl:template>   
</xsl:stylesheet>

department但它返回所有节点的子值。

<child2value>bar2 baz2 foo2</child2value>
<child3value>bar3 baz3 foo3</child3value>

我知道我在这里缺少一个关于如何将节点设置为当前节点的关键概念。感谢您对这个新手的任何建议。

4

2 回答 2

0

我将解决如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs">

<xsl:param name="dep-url" as="xs:string" select="'test2013033102.xml'"/>
<xsl:variable name="dep-doc" as="document-node()" select="doc($dep-url)"/>

<xsl:output method="xml" indent="yes" />

<xsl:key name="by-child" match="department" use="*"/>

<xsl:template match="/">
  <xsl:variable name="source" as="element(sourceElement)*" select="sourceRoot/sourceElement"/>
  <xsl:apply-templates select="key('by-child', $source, $dep-doc)/*[not(. = $source)]"/>
</xsl:template>

<xsl:template match="department/*">
  <xsl:element name="{name()}value">
    <xsl:value-of select="."/>
  </xsl:element>
</xsl:template>

</xsl:stylesheet>

这会将您的输入转换为

<?xml version="1.0" encoding="UTF-8"?>
<child2value>foo2</child2value>
<child3value>foo3</child3value>
于 2013-03-31T16:01:11.557 回答
0

您可以通过单个 XPath 表达式选择您想要的内容,如以下转换所示:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="sourceElement">
     <xsl:copy-of select=
     "document('file:///c:/temp/delete/dept.xml')
               /*/*[child1 = current()]
                     /*[not(self::child1)]
     "/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<sourceRoot>
 <sourceElement>foo</sourceElement>
</sourceRoot>

第二个提供的 XML 文档位于本地文件系统中c:\temp\delete\dept.xml

<departments>
 <department>
  <child1>bar</child1>
  <child2>bar2</child2>
  <child3>bar3</child3>
 </department>
 <department>
  <child1>baz</child1>
  <child2>baz2</child2>
  <child3>baz3</child3>
 </department>
 <department>
  <child1>foo</child1>
  <child2>foo2</child2>
  <child3>foo3</child3>
 </department>
</departments>

产生了想要的正确结果:

<child2>foo2</child2>
<child3>foo3</child3>

更新

如果我们想更改上面选定元素的名称,这真的很简单:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="sourceElement">
     <xsl:apply-templates select=
     "document('file:///c:/temp/delete/dept.xml')
               /*/*[child1 = current()]
                     /*[not(self::child1)]
     "/>
 </xsl:template>

 <xsl:template match="*[starts-with(name(), 'child')]">
  <xsl:element name="{name()}value"><xsl:value-of select="."/></xsl:element>
 </xsl:template>
</xsl:stylesheet>

产生

<child2value>foo2</child2value>
<child3value>foo3</child3value>
于 2013-03-31T16:29:03.400 回答