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

Adding a namespace in the root element for use in attribute of child element

我从 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 实现这一点?

您只需添加一个与父元素匹配的模板 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