在根元素中添加一个名称空间,以用于子元素的属性

时间:2019-02-22 09:03:47

标签: xml xslt xml-namespaces

我从JUnit获得以下输出:

<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="Some Collection" tests="13" time="1.174">
  <testsuite name="Request 1"/>
  <testsuite name="Request 2">
    <testcase name="Status code is 200" time="0.083"/>
  </testsuite>
  <testsuite name="Request 3">
    <testcase name="Status code is 200" time="0.056"/>
    <testcase name="Validation message is triggered" time="0.056"/>
  </testsuite>
<testsuites>

在这种情况下,testsuites是我的根元素。为了将其正确转换为JSON,我需要在testsuitetestcase元素中添加以下属性:json:Array="true",我使用XSL做到这一点:

<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:json="http://james.newtonking.com/projects/json">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="//testsuite">
  <xsl:copy>
   <xsl:attribute name="json:Array">true</xsl:attribute> 
   <xsl:apply-templates select="node()|@*" /> 
  </xsl:copy>
 </xsl:template>

 <xsl:template match="//testcase">
  <xsl:copy>
   <xsl:attribute name="json:Array">true</xsl:attribute> 
   <xsl:apply-templates select="node()|@*" /> 
  </xsl:copy>
 </xsl:template>
</xsl:transform>

这将导致以下(有效)xml:

<testsuites name="Some Collection" tests="13" time="1.174">
  <testsuite xmlns:json="http://james.newtonking.com/projects/json" json:Array="true" name="Request 1"/>
  <testsuite xmlns:json="http://james.newtonking.com/projects/json" json:Array="true" name="Request 2">
    <testcase xmlns:json="http://james.newtonking.com/projects/json" json:Array="true" name="Status code is 200" time="0.083"/>
  </testsuite>
  <testsuite xmlns:json="http://james.newtonking.com/projects/json" json:Array="true" name="Request 3">
    <testcase xmlns:json="http://james.newtonking.com/projects/json" json:Array="true" name="Status code is 200" time="0.056"/>
    <testcase xmlns:json="http://james.newtonking.com/projects/json" json:Array="true" name="Validation message is triggered" time="0.056"/>
  </testsuite>
<testsuites>

但是我真正想要的是将名称空间移至根元素,以便可以在子元素中使用

<testsuites xmlns:json="http://james.newtonking.com/projects/json" name="Some Collection" tests="13" time="1.174">
  <testsuite json:Array="true" name="Request 1"/>
  <testsuite json:Array="true" name="Request 2">
    <testcase json:Array="true" name="Status code is 200" time="0.083"/>
  </testsuite>
  <testsuite json:Array="true" name="Request 3">
    <testcase json:Array="true" name="Status code is 200" time="0.056"/>
    <testcase json:Array="true" name="Validation message is triggered" time="0.056"/>
  </testsuite>
<testsuites>

如何使用XSLT实现呢?

1 个答案:

答案 0 :(得分:1)

您只需要添加一个与父元素testsuites匹配的模板,如下所示:

<xsl:transform version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:json="http://james.newtonking.com/projects/json">
    <xsl:output omit-xml-declaration="yes" indent="yes" />

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="//testsuite">
        <xsl:copy>
            <xsl:attribute name="json:Array">true</xsl:attribute>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="//testcase">
        <xsl:copy>
            <xsl:attribute name="json:Array">true</xsl:attribute>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="//testsuites">
        <testsuites xmlns:json="http://james.newtonking.com/projects/json">
            <xsl:apply-templates select="node()|@*" />
        </testsuites>
    </xsl:template>
</xsl:transform>

http://xsltransform.net/asnmyQ