0

私はこのソースxmlを持っています:

<source>
 <category id="1" />  
 <item1 />
 <item2 />
 <category id="2"/>
 <item1 />
 <item2 />
</source>

ご覧のとおり、すべてのアイテムが同じ階層を持っています。そして、次のように別の XML に「変換」/シリアル化する必要があります。

 <source>
   <category id="1">
     <item1  />
     <item2  />
   </category>
   <category id="2">
      <item1  />
      <item2  />
    </category>
 </source>

「アイテム」は「カテゴリ」の子です。

XmlPullParser と XmlSerializer は Android ツールから使用していますが、Android 環境と互換性がある場合は別のものを使用してもかまいません。

送信

4

2 に答える 2

1

XSLT を使用する別の方法を見つけました。この方法では、オブジェクトを含むデータを処理せずに、XML 専用の特定のツールを使用して変換します。

変換を処理するための transform.xsl ファイルを作成します。

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" encoding="UTF-8" />
    <xsl:strip-space elements="*" />
    <xsl:template match="/">
        <xsl:apply-templates />
    </xsl:template>
    <xsl:template match="source">
        <source>
            <xsl:apply-templates select="category" />
        </source>
    </xsl:template>
    <xsl:template match="category">
        <xsl:variable name="place" select="count(preceding-sibling::category)" />
        <category>
            <xsl:attribute name="id">
    <xsl:value-of select="@id" />
  </xsl:attribute>
            <xsl:apply-templates select="following-sibling::*[not(self::category)]">
                <xsl:with-param name="slot" select="$place" />
            </xsl:apply-templates>
        </category>
    </xsl:template>
    <xsl:template match="item1">
        <xsl:param name="slot" />
        <xsl:choose>
            <xsl:when test="count(preceding-sibling::category) = $slot + 1">
                <xsl:copy-of select="." />
            </xsl:when>
            <xsl:otherwise />
        </xsl:choose>
    </xsl:template>
    <xsl:template match="item2">
        <xsl:param name="slot" />
        <xsl:choose>
            <xsl:when test="count(preceding-sibling::category) = $slot + 1">
                <xsl:copy-of select="." />
            </xsl:when>
            <xsl:otherwise />
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

次に、必要な出力 data.xml を含むファイルへの変換を処理するコードを記述します。

         AssetManager am = getAssets();
         xml = am.open("source.xml");
         xsl = am.open("transform.xsl");

        Source xmlSource = new StreamSource(xml);
        Source xsltSource = new StreamSource(xsl);

        TransformerFactory transFact = TransformerFactory.newInstance();
        Transformer trans = transFact.newTransformer(xsltSource);


        File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/data.xml");
        StreamResult result = new StreamResult(f);
        trans.transform(xmlSource, result);

そして、それは完了です。詳細はこちら: http://www.dpawson.co.uk/xsl/sect2/flatfile.html

于 2011-12-28T17:21:58.480 に答える
0

簡単なxml形式の場合、これはそれほど難しいことではありません。

saxパーサーを使用して最初のxmlファイルを読み取るための可能な方法は次のとおりです。

public class MySaxHandler extends DefaultHandler {
  private List<Category> items = new LinkedList<Category>();
  private Category currentCategory;
  public void startElement(String uri, String localName, String qName, Attributes attributes) {
    if (localName.equals("category")) {
      currentCategory = new Category(attributes.getValue("id"));
      items.add(currentCategory);
    }
    if (localName.equals("item1") {
      currentCategory.setItem1(new Item1(...));
    }
    if (localName.equals("item2") {
      currentCategory.setItem2(new Item2(...));
    }
  }
}

タグごと<category>に、新しいCategoryオブジェクトを作成します。最後のカテゴリオブジェクトに次のアイテムが追加されます。コンテンツを読みながら、後で必要な階層を作成します(アイテムは適切なカテゴリに追加されます)。このコードを変換して、saxパーサーの代わりにXmlPullParserを使用するのは簡単です。サックスに慣れているので、サックスを使いました。

最初のファイルの読み取りが終了したら、階層を新しいファイルに書き込む必要があります。

次のような方法でこれを行うことができます。

StringBuilder b = new StringBuilder();
for (int i = 0; i < categories.size(); i++) {
  b.append(categories.get(i).getXml());
}
// write content of b into file

getXml()各カテゴリは次のようになります。

public String getXml() {
  StringBuilder b = new StringBuilder();
  b.append("<category id=\"" + this.id + "\">");
  for (int i = 0; i < items.size(); i++) {
    b.append(items.get(i).getXml());
  }
  b.append("</category>");
  return b.toString();
}

getXml()各アイテムは、そのメソッドに独自のxmlを作成します。

public String getXml() {
  return "<item1 />";
}

最も簡単な場合。

手作業でxmlを作成するのは、xml構造がそれほど単純なままである場合にのみ適していることに注意してください。構造がより複雑になっている場合は、Androidで動作する軽量のxmlライブラリ(xstreamなど)を利用する必要があります。

于 2011-12-28T01:58:39.797 に答える