如何在android中从另一个xml变化层次序列化xml
我得到了这个源xml:如何在android中从另一个xml变化层次序列化xml,android,xslt,xml-serialization,xmlpullparser,Android,Xslt,Xml Serialization,Xmlpullparser,我得到了这个源xml: <source> <category id="1" /> <item1 /> <item2 /> <category id="2"/> <item1 /> <item2 /> </source> 正如您所看到的,所有项目都具有相同的层次结构。 我需要将其“翻译”/序列化为另一个XML,如下所示: <source> <categor
<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>
StringBuilder b = new StringBuilder();
for (int i = 0; i < categories.size(); i++) {
b.append(categories.get(i).getXml());
}
// write content of b into file
其中“项目”是“类别”的子项
我正在使用Android工具中的XmlPullParser和XmlSerializer,但如果它们与Android环境兼容,我不介意使用另一个
Tx对于一种简单的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(...));
}
}
}
每个类别的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();
}
在最简单的情况下
请注意,手工构建xml只适用于xml结构保持简单的情况。如果结构变得越来越复杂,您应该使用一些在Android上工作的轻量级xml库(如)。我找到了使用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>
一切都结束了。
更多信息请点击此处:
我到处都在读。XSLT可能是答案吗?它应该有效。但是你必须把所有的信息载入内存。我的想法是以“流”的方式来做。我的意思是一步读数据,一步构建。但由于我没有明确说明,我会检查你的答案是否正确,因为它当然是正确的。非常感谢。
<?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>
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);