如何从另一个 xml 更改层次结构序列化 android 中的 xml

发布于 2024-12-23 04:41:57 字数 631 浏览 2 评论 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>

其中“items”是“category”的子级。

兼容,我不介意使用另一个

我正在使用 Android 工具中的 XmlPullParser 和 XmlSerializer,但如果它们与 Android 环境Tx

I've got this source xml:

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

As you can see all items have the same hierarchy.
And I need to "translate"/serialize it to another XML like this:

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

Where "items" are children of "category".

I'm using XmlPullParser and XmlSerializer from Android tools but I don't mind to use another if they are compatible with Android environment

Tx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

终陌 2024-12-30 04:41:57

我找到了另一种使用 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

I've found another way using XSLT:
This way we use XML-only specific tools for transform without handling any data with objects.

create a transform.xsl file to handle transformation:

<?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>

And then write the code to handle transformation to a file with desired output 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);

And its done.
more info here:
http://www.dpawson.co.uk/xsl/sect2/flatfile.html

花开浅夏 2024-12-30 04:41:57

对于简单的 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 对象。以下项目将添加到最后一个类别对象中。在阅读内容时,您可以创建稍后需要的层次结构(项目将添加到适当的类别)。
将此代码转换为使用 XmlPullParser 而不是 sax 解析器应该很容易。我只是用萨克斯,因为我更熟悉它。

读完第一个文件后,您需要将层次结构写入新文件。

您可以通过如下方式执行此操作:

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) 。

For an easy xml format this shouldn't be that hard.

A possible way to read the first xml file with a sax parser would be:

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(...));
    }
  }
}

For each <category> tag you create a new Category object. The following items will be added to the last category object. While reading the contents you create the hierarchy you need later (items are added to the appropriate category).
It should be easy to transform this code to use XmlPullParser instead of sax parser. I just used sax because I am more familiar with it.

When you finished reading the first file you need to write your hierarchy to a new file.

You can do this in a way like this:

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() for each category could look like:

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();
}

Each item creates its own xml in its getXml() method which could be

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

in the easiest case.

Please note that building xml by hand is only suitable if you xml structure stays that simple. If the structure is becoming more complicated you should make use of some lightweight xml libraries that work on Android (like xstream).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文