使用StAX轻松修改XML

时间:2020-07-17 16:03:34

标签: java xml stax

我试图修改现有的XML文件。据我所知,不可能直接进行操作,所以我的想法是读取流中的文件,对其进行修改,创建一个新文件,然后将旧文件替换为新文件。
我只需要应用简单的更改,所以我决定采用StAX方法,因为它适合于处理大量数据或进行简单处理。

现有的XML文件:

runfile('C:/Users/Sriram/.spyder-py3/temp.py', wdir='C:/Users/Sriram/.spyder-py3')
Traceback (most recent call last):

  File "C:\Users\Sriram\.spyder-py3\temp.py", line 30, in <module>
    content_image_tensor = image_to_tensor(content_path)

  File "C:\Users\Sriram\.spyder-py3\temp.py", line 20, in image_to_tensor
    img = tf.image.resize(img, [720, 512])

  File "C:\Users\Sriram\anaconda3\lib\site-packages\tensorflow\python\ops\image_ops_impl.py", line 1182, in resize_images
    skip_resize_if_same=True)

  File "C:\Users\Sriram\anaconda3\lib\site-packages\tensorflow\python\ops\image_ops_impl.py", line 1029, in _resize_images_common
    raise ValueError('\'images\' contains no shape.')

ValueError: 'images' contains no shape

所需的输出:

<?xml version='1.0' encoding='UTF-8'?>
<Company>
    <Employee>
        <FirstName>Tanmay</FirstName>
        <LastName>Patil</LastName>
        <ContactNo>1234567890</ContactNo>
        <Address>
            <City>Bangalore</City>
            <State>Karnataka</State>
            <Zip>560212</Zip>
        </Address>
    </Employee>
</Company>

此代码仅复制一个XML文件(source):

<?xml version='1.0' encoding='UTF-8'?>
<Company>
    <Employee>
        <FirstName>Tanmay</FirstName>
        <LastName>Patil</LastName>
        <ContactNo>1234567890</ContactNo>
        <Address>
            <City>Bangalore</City>
            <State>Karnataka</State>
            <NewElem>Some value</NewElem> <!-- Replacing all ZIP-elements -->
        </Address>
    </Employee>
</Company>

它可以工作,但是我不确定public static void writeAll(XMLStreamReader xmlr, XMLStreamWriter writer) throws XMLStreamException { while (xmlr.hasNext()) { write(xmlr, writer); xmlr.next(); } write(xmlr, writer); // write the last element writer.flush(); } public static void write(XMLStreamReader xmlr, XMLStreamWriter writer) throws XMLStreamException { switch (xmlr.getEventType()) { case XMLEvent.START_ELEMENT: final String localName = xmlr.getLocalName(); final String namespaceURI = xmlr.getNamespaceURI(); if (namespaceURI != null && namespaceURI.length() > 0) { final String prefix = xmlr.getPrefix(); if (prefix != null) { writer.writeStartElement(prefix, localName, namespaceURI); } else { writer.writeStartElement(namespaceURI, localName); } } else { writer.writeStartElement(localName); } for (int i = 0, len = xmlr.getNamespaceCount(); i < len; i++) { writer.writeNamespace(xmlr.getNamespacePrefix(i), xmlr.getNamespaceURI(i)); } for (int i = 0, len = xmlr.getAttributeCount(); i < len; i++) { String attUri = xmlr.getAttributeNamespace(i); if (attUri != null) { writer.writeAttribute(attUri, xmlr.getAttributeLocalName(i), xmlr.getAttributeValue(i)); } else { writer.writeAttribute(xmlr.getAttributeLocalName(i), xmlr.getAttributeValue(i)); } } break; case XMLEvent.END_ELEMENT: writer.writeEndElement(); break; case XMLEvent.SPACE: case XMLEvent.CHARACTERS: writer.writeCharacters(xmlr.getTextCharacters(), xmlr.getTextStart(), xmlr.getTextLength()); break; case XMLEvent.PROCESSING_INSTRUCTION: writer.writeProcessingInstruction(xmlr.getPITarget(), xmlr.getPIData()); break; case XMLEvent.CDATA: writer.writeCData(xmlr.getText()); break; case XMLEvent.COMMENT: writer.writeComment(xmlr.getText()); break; case XMLEvent.ENTITY_REFERENCE: writer.writeEntityRef(xmlr.getLocalName()); break; case XMLEvent.START_DOCUMENT: String encoding = xmlr.getCharacterEncodingScheme(); String version = xmlr.getVersion(); if (encoding != null && version != null) { writer.writeStartDocument(encoding, version); } else if (version != null) { writer.writeStartDocument(xmlr.getVersion()); } break; case XMLEvent.END_DOCUMENT: writer.writeEndDocument(); break; case XMLEvent.DTD: writer.writeDTD(xmlr.getText()); break; } } 的复杂性。那些开关盒真的必要吗?


我也遇到了问题,将ZIP元素替换为

write()-method

替换XML文件中的某些节点的最有效方法是什么?

1 个答案:

答案 0 :(得分:1)

XSLT具有所谓的“身份转换”模式。

有用的链接:XSL Identity Transforms

下面的XSLT将按原样复制整个输入XML,但Zip元素除外。找到Zip元素后,它将被新的所需标签替换。

您要做的只是从Java代码中调用XSLT转换。

输入XML

<?xml version="1.0" encoding="UTF-8"?>
<Company>
    <Employee>
        <FirstName>Tanmay</FirstName>
        <LastName>Patil</LastName>
        <ContactNo>1234567890</ContactNo>
        <Address>
            <City>Bangalore</City>
            <State>Karnataka</State>
            <Zip>560212</Zip>
        </Address>
    </Employee>
</Company>

XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml" encoding="utf-8"/>

    <!-- IdentityTransform -->
    <xsl:template match="/ | @* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Zip">
        <NewElem>Some value</NewElem>
    </xsl:template>

</xsl:stylesheet>

输出XML

<?xml version='1.0' encoding='utf-8' ?>
<Company>
  <Employee>
    <FirstName>Tanmay</FirstName>
    <LastName>Patil</LastName>
    <ContactNo>1234567890</ContactNo>
    <Address>
      <City>Bangalore</City>
      <State>Karnataka</State>
      <NewElem>Some value</NewElem>
    </Address>
  </Employee>
</Company>