Java XML ו- JSON: עיבוד מסמכים עבור Java SE, חלק 1: SAXON וג'קסון

הקודם 1 2 עמוד 2 עמוד 2 מתוך 2

טרנספורמציה

עכשיו בואו ננסה את השינוי. בצע את הפקודה הבאה:

java XSLTDemo books.xml books.xsl

למרבה הצער, טרנספורמציה זו נכשלת: עליכם לצפות בפלט המזהה את אפאצ'י קסלן כמפעל השנאים והודעת שגיאה המציינת xsl:for-each-groupשאינה נתמכת.

בוא ננסה שוב. בהנחה saxon9he.jarו XSLTDemo.classממוקמים בספרייה הנוכחית, לבצע את הפקודה הבאה:

java -cp saxon9he.jar;. XSLTDemo books.xml books.xsl

הפעם, עליך להתבונן בפלטים הממוינים והקובצים כהלכה הבאים:

תוספת לפרק 11: עיבוד JSON עם ג'קסון

המרת XML ל- JSON עם ג'קסון

Java XML ו- JSON, פרק 11, מציג את ג'קסון, המספק ממשקי API לניתוח ויצירת אובייקטים של JSON. אפשר גם להשתמש בג'קסון כדי להמיר מסמכי XML למסמכי JSON.

בחלק זה, אראה לך שתי דרכים להמיר XML ל- JSON, תחילה באמצעות איגוד נתונים ואז עם מעבר עץ. אני מניח שקראת את פרק 11 ואתה מכיר את ג'קסון. על מנת לעקוב אחר הדגמות אלה, היית צריך להוריד את קבצי ה- JAR הבאים ממאגר Maven:

  • jackson-annotations-2.9.7.jar
  • jackson-core-2.9.7.jar
  • jackson-databind-2.9.7.jar

תצטרך גם כמה קבצי JAR נוספים; רובן נפוצות בשתי טכניקות ההמרה. אמסור מידע על השגת קבצי JAR אלה בקרוב.

המרת XML ל- JSON באמצעות קשירת נתונים

קשירת נתונים מאפשרת לך למפות נתונים מסודרים לאובייקט Java. לדוגמא, נניח שיש לך מסמך XML קטן שמתאר כוכב לכת יחיד. רישום 4 מציג מסמך זה.

רישום 4. planet.xml

  Earth 3 9 

רישום 5 מציג Planetמחלקת Java שווה ערך שהאובייקטים שלה ממפות planet.xmlלתוכן.

רישום 5. Planet.java

public class Planet { public String name; public Integer planet_from_sun; public Integer moons; }

תהליך ההמרה מחייב לנתח את ה- XML Planetלאובייקט. אתה יכול לבצע משימה זו על ידי עבודה עם com.fasterxml.jackson.dataformat.xml.XmlMapperהכיתה באופן הבא:

XmlMapper xmlMapper = new XmlMapper(); XMLInputFactory xmlif = XMLInputFactory.newFactory(); FileReader fr = new FileReader("planet.xml"); XMLStreamReader xmlsr = xmlif.createXMLStreamReader(fr); Planet planet = xmlMapper.readValue(xmlsr, Planet.class);

XmlMapperהוא מותאם אישית com.fasterxml.jackson.databind.ObjectMapperשקורא וכותב XML. הוא מספק מספר readValue()שיטות לקריאת ערך XML יחיד ממקור קלט ספציפי ל- XML; לדוגמה:

 T readValue(XMLStreamReader r, Class valueType)

כל readValue()שיטה דורשת javax.xml.stream.XMLStreamReaderאובייקט כטיעון הראשון שלה. אובייקט זה הוא למעשה מנתח מבוסס זרם מבוסס StAX לניתוח טקסט בצורה יעילה בצורה קדימה.

הטיעון השני הוא java.lang.Classאובייקט לסוג היעד שמתבצע באופן מיידי, מאוכלס בנתוני XML, ואשר המופע שלו מוחזר לאחר מכן מהשיטה.

השורה התחתונה של קטע קוד זה היא שתוכן הרישום 4 נקרא Planetלאובייקט readValue()שחוזר למתקשר שלו.

לאחר שנוצר האובייקט, קל לכתוב אותו כ- JSON על ידי עבודה עם השיטה ObjectMapperשלו String writeValueAsString(Object value):

ObjectMapper jsonMapper = new ObjectMapper(); String json = jsonMapper.writeValueAsString(planet);

קטעתי את שברי הקוד הללו XML2JSONמיישום שקוד המקור השלם שלו מופיע ברשימה 6.

רישום 6. XML2JSON.java (גרסה 1)

import java.io.FileReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import static java.lang.System.*; public class XML2JSON { public static void main(String[] args) throws Exception { XmlMapper xmlMapper = new XmlMapper(); XMLInputFactory xmlif = XMLInputFactory.newFactory(); FileReader fr = new FileReader("planet.xml"); XMLStreamReader xmlsr = xmlif.createXMLStreamReader(fr); Planet planet = xmlMapper.readValue(xmlsr, Planet.class); ObjectMapper jsonMapper = new ObjectMapper(); String json = jsonMapper.writeValueAsString(planet); out.println(json); } }

לפני שתוכל לאסוף רישומים 5 ו -6, תצטרך להוריד את ג'קסון Dataformat XML, אשר מיושם XMLMapper. הורדתי את גרסת 2.9.7, שתואמת לגרסאות שלושת חבילות ג'קסון האחרות.

בהנחה שהורדת בהצלחה jackson-dataformat-xml-2.9.7.jar, בצע את הפקודה הבאה (להתפשט על שתי שורות לקריאות) כדי לקמפל את קוד המקור:

javac -cp jackson-core-2.9.7.jar;jackson-databind-2.9.7.jar;jackson-dataformat-xml-2.9.7.jar;. XML2JSON.java

לפני שתוכל להריץ את היישום שהתקבל, יהיה עליך להוריד את מודול ג'קסון: JAXB Annotations, וגם להוריד את StAX 2 API. הורדתי את JAXB Annotations גרסה 2.9.7 ו- StAX 2 API גרסה 3.1.3.

בהנחה שהורדת בהצלחה jackson-module-jaxb-annotations-2.9.7.jarו stax2-api-3.1.3.jar, לבצע את הפקודה הבאה (התפשטות על פני שלושה קווים עבור הקריאות) כדי להפעיל את היישום:

java -cp jackson-annotations-2.9.7.jar;jackson-core-2.9.7.jar;jackson-databind-2.9.7.jar; jackson-dataformat-xml-2.9.7.jar;jackson-module-jaxb-annotations-2.9.7.jar; stax2-api-3.1.3.jar;. XML2JSON

אם הכל מסתדר כשורה, עליך להתבונן בפלט הבא:

{"name":"Earth","planet_from_sun":3,"moons":9}

המרת XML ל- JSON באמצעות מעבר עצים

דרך נוספת להמיר מ- XML ​​ל- JSON היא לנתח את ה- XML ​​לעץ של צמתים JSON ואז לכתוב עץ זה למסמך JSON. אתה יכול לבצע את המשימה הראשונה על ידי קריאה לאחת מהשיטות XMLMapperשעברו בירושה readTree():

XmlMapper xmlMapper = new XmlMapper(); JsonNode node = xmlMapper.readTree(xml.getBytes());

ObjectMapperים" JsonNode readTree(byte[] content)שיטת deserializes תוכן JSON לתוך עץ של jackson.databind.JsonNodeאובייקטים, ומחזירה את השורש JsonNodeמושא העץ הזה. XmlMapperבהקשר, שיטה זו מבטל את עריכת תוכן ה- XML ​​לעץ. בשני המקרים, תוכן JSON או XML מועברים לשיטה זו כמערך של בתים.

המשימה השנייה - המרת עץ האובייקטים ל- JSON - מתבצעת באופן דומה למה שהראיתי בעבר. הפעם, זהו JsonNodeאובייקט השורש שעובר ל writeValueAsString():

ObjectMapper jsonMapper = new ObjectMapper(); String json = jsonMapper.writeValueAsString(node);

I excerpted these code fragments from an XML2JSON application whose complete source code appears in Listing 7.

Listing 7. XML2JSON.java (version 2)

import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import static java.lang.System.*; public class XML2JSON { public static void main(String[] args) throws Exception { String xml = "\n"+ "\n" + " Earth\n" + " 3\n" + " 1\n" + "\n"; XmlMapper xmlMapper = new XmlMapper(); JsonNode node = xmlMapper.readTree(xml.getBytes()); ObjectMapper jsonMapper = new ObjectMapper(); String json = jsonMapper.writeValueAsString(node); out.println(json); } }

Execute the following command (spread over two lines for readability) to compile Listing 7:

javac -cp jackson-core-2.9.7.jar;jackson-databind-2.9.7.jar;jackson-dataformat-xml-2.9.7.jar XML2JSON.java

Before you can run the resulting application, you'll need to download Woodstox, which is a high-performance XML processor that implements StAX, SAX2, and StAX2. I downloaded Woodstox 5.2.0. Then execute the following command (spread across three lines for readability) to run the application:

java -cp jackson-annotations-2.9.7.jar;jackson-core-2.9.7.jar;jackson-databind-2.9.7.jar; jackson-dataformat-xml-2.9.7.jar;stax2-api-3.1.3.jar;woodstox-core-5.2.0.jar;. XML2JSON

If all goes well, you should observe the following output:

{"name":"Earth","planet_from_sun":"3","moons":"1"}

Notice that the numbers assigned to the planet_from_sun and moons XML elements are serialized to JSON strings instead of numbers. The readTree() method doesn't infer the data type in the absence of an explicit type definition.

Jackson's support for XML tree traversal has additional limitations:

  • Jackson is unable to differentiate between objects and arrays. Because XML provides no means to differentiate an object from a list (array) of objects, Jackson collates repeated elements into a single value.
  • Jackson doesn't support mixed content (textual content and elements as children of an element). Instead, it maps each XML element to a JsonNode object. Any text is lost.

Given these limitations, it's not surprising that the official Jackson documentation recommends against parsing XML into JsonNode-based trees. You're better off using the data binding conversion technique.

Conclusion

יש לראות בחומר המוצג במאמר זה כתוספת לפרקים 6 ו -11 במהדורה השנייה של Java XML ו- JSON . לעומת זאת, המאמר הבא שלי יהיה קשור לספר אך חומר חדש לחלוטין. עקוב אחר המאמר הקרוב שלי על קשירת אובייקטים של Java למסמכי JSON עם JSON-B.

סיפור זה, "Java XML ו- JSON: עיבוד מסמכים עבור Java SE, חלק 1: SAXON וג'קסון" פורסם במקור על ידי JavaWorld.