xslt转换为omly从xml复制到xml特定节点

时间:2017-07-04 13:12:55

标签: xml xslt

我需要创建一些xml文件的子xml。 我有一个必需的节点列表。 xslt变形应该如何? 例如,输入文件:

<?xml version="1.0"?>
<root>
  <a id="A">
    <aa>text</aa>
    <bb>text</bb>
    <cc id="1">
      <aaa>text</aaa>
      <bbb>text</bbb>
    </cc>
  </a>
  <a id="B">
    <aa>text2</aa>
    <bb>text2</bb>
    <cc id="2">
      <aaa>text2</aaa>
      <bbb>text2</bbb>      
    </cc>
  </a>
</root>

期望的输出:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <a id="A">
      <bb>text</bb>
      <cc>
         <bbb>text</bbb>
      </cc>
   </a>
   <a id="B">
      <bb>text2</bb>
      <cc>
         <bbb>text2</bbb>
      </cc>
   </a>
</root>

目前我使用follwonf xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
  <xsl:output indent="yes"/>

  <xsl:template match="node()|@*"/>

  <xsl:template match="
 root
|root/a
|root/a/@id
|root/a/bb
|root/a/bb/node()
|root/a/cc
|root/a/cc/bbb
|root/a/cc/bbb/node()
 ">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

但我希望有更短的清单:

 root/a/@id
|root/a/bb/node()
|root/a/cc/bbb/node()

那么如何为该短名单创建xslt转换?

3 个答案:

答案 0 :(得分:0)

我会更具体:

<强> XSLT

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class CustomHttpClient {
    private static HttpClient custHttpClient;
    public static final int MAX_TOTAL_CONNECTIONS = 1000;
    public static final int MAX_CONNECTIONS_PER_ROUTE = 1500;
    public static final int TIMEOUT_CONNECT = 150000;
    public static final int TIMEOUT_READ = 150000;
    public static HttpClient getHttpClient() {
    if (custHttpClient == null) {
            SchemeRegistry schemeRegistry = new SchemeRegistry();
            schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            schemeRegistry.register(new Scheme("https",SSLSocketFactory.getSocketFactory(), 443));
            HttpParams connManagerParams = new BasicHttpParams();
            ConnManagerParams.setMaxTotalConnections(connManagerParams, MAX_TOTAL_CONNECTIONS);
            ConnManagerParams.setMaxConnectionsPerRoute(connManagerParams, new ConnPerRouteBean(MAX_CONNECTIONS_PER_ROUTE));
            HttpConnectionParams.setConnectionTimeout(connManagerParams, TIMEOUT_CONNECT);
            HttpConnectionParams.setSoTimeout(connManagerParams, TIMEOUT_READ);
            ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(new BasicHttpParams(), schemeRegistry);
            custHttpClient = new DefaultHttpClient(cm, null);
            HttpParams para = custHttpClient.getParams();
            HttpConnectionParams.setConnectionTimeout(para, (30 * 10000));
            HttpConnectionParams.setSoTimeout(para, (30 * 10000));
            ConnManagerParams.setTimeout(para, (30 * 10000));
        }
        return custHttpClient;
    }
    public static String executePost(String urlPostFix,ArrayList<NameValuePair> postedValues)
    throws Exception {
        String url = urlPostFix;
        BufferedReader in = null;
        try {
            System.setProperty("http.keepAlive", "false");
            HttpClient client = getHttpClient();
            HttpPost request = new HttpPost(url);
            request.setHeader("Accept", "application/json");
            request.setHeader("Content-Type", "application/x-www-form-urlencoded");
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postedValues);
            formEntity.setContentType("application/json");
            request.setEntity(formEntity);
            HttpResponse response = client.execute(request);
            in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuffer sb = new StringBuffer("");
            String line = "";
            String NL = System.getProperty("line.separator");
            while ((line = in.readLine()) != null) {
                sb.append(line + NL);
            }
            in.close();
            String result = sb.toString();
            return result;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
    }
    public static String executeGet(String urlPostFix)
            throws Exception {
                String url = urlPostFix;
                BufferedReader in = null;
                try {
                    HttpClient client = getHttpClient();
                    HttpGet request = new HttpGet( url);
                    request.setHeader("Accept", "application/json");
                    request.setHeader("Content-Type", "application/x-www-form-urlencoded");
                    HttpResponse response = client.execute(request);
                    in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
                    StringBuffer sb = new StringBuffer("");
                    String line = "";
                    String NL = System.getProperty("line.separator");
                    while ((line = in.readLine()) != null) {
                        sb.append(line + NL);
                    }
                    in.close();
                    String result = sb.toString();
                    return result;
                } finally {
                    if (in != null) {
                        try {
                            in.close();
                        } catch (IOException e) {
                        }
                    }
                }
            }
    public static Bitmap executeImageGet(String urlPostFix)
            throws Exception {
                String url = urlPostFix;
                InputStream in = null;
                try {
                    HttpClient client = getHttpClient();
                    HttpGet request = new HttpGet(url);
                    HttpResponse response = client.execute(request);
                    HttpEntity entity = response.getEntity();
                    BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
                    in = bufHttpEntity.getContent();
                    Bitmap bitmap = BitmapFactory.decodeStream(in);
                    in.close();
                    return bitmap;
                } finally {
                    if (in != null) {
                        try {
                            in.close();
                        } catch (IOException e) {
                        }
                }
                }
    }
}

答案 1 :(得分:0)

那么,在XSLT 2.0中,您可以使用带有这些节点的变量,计算另一个变量中的祖先,然后按如下方式使用这些变量:

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

    <xsl:output indent="yes"/>

    <xsl:variable name="copy"
        select="
        root/a/@id
        |root/a/bb/node()
        |root/a/cc/bbb/node()"/>

    <xsl:variable name="subtrees" select="$copy/ancestor-or-self::node()"/>

    <xsl:template match="*[. intersect $subtrees]">
        <xsl:copy>
            <xsl:copy-of select="@*[. intersect $copy]"/>               
            <xsl:apply-templates select="node()[. intersect $subtrees]"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

在使用static parametershadow attribute的XSLT 3.0中,您甚至可以进一步参数化:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="3.0">

    <xsl:param name="paths" static="yes" as="xs:string"
        select="'root/a/@id | root/a/bb/node() | root/a/cc/bbb/node()'"/>

    <xsl:output indent="yes"/>

    <xsl:variable name="copy" _select="{$paths}"/>

    <xsl:variable name="subtrees" select="$copy/ancestor-or-self::node()"/>

    <xsl:template match="*[. intersect $subtrees]">
        <xsl:copy>
            <xsl:copy-of select="@*[. intersect $copy]"/>               
            <xsl:apply-templates select="node()[. intersect $subtrees]"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

答案 2 :(得分:0)

在XSLT 1.0中,我建议进行以下转换:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="@*|node()">
    <xsl:if test="not(. = following-sibling::*)">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

它选择具有相同值的每个最后一个节点。