Seite 1 von 1
XML - Ampersand (&) in setXMLNodeText
Verfasst: 30.03.2022 19:37
von ThorKonnat
Guten Tag,
ich versuche, aus Purebasic heraus eine spreadsheetML Datei für Microsot Excel zu erzeugen.
Um einen Text 2-zeilig in eine Zelle zu schreiben, muss der Text mit " " getrennt werden.
Beispiel:
<Data ss:Type="String">Text Zeile1 Text Zeile2</Data>
Ein normaler Zeilenumbruch wird von EXCEL durch Leerzeichen ersetzt.
Nun meine Frage: Wie bekomme ich es hin, dass setXMLNodeText das & Zeichen nicht durch ein & interpretiert?
Alle meine Versuche, das & zu maskieren erzeugen immer wieder "&#10;"
Vielen Dank
Re: XML - Ampersand (&) in setXMLNodeText
Verfasst: 30.03.2022 20:14
von TroaX
Nur jetzt ins blaue geraten. Aber verwendest du für das XML auch Unicode bzw. UTF8 als Kodierung? Ich bin bei Markups eher gewohnt, das nur umgewandelt wird, wenn die Anwendung einen begrenzten Zeichensatz erwartet. Früher hat man das & in HTML gegen die Entität & ausgetauscht. Aber seit es in HTML üblich geworden ist, den Zeichensatz anzugeben, benötigt man die aller meisten Entitäten nicht mehr bzw. werden nur noch zum entschärfen von Inlinecodes (z.B. gegen Cross-Site-Scripting) verwendet.
Re: XML - Ampersand (&) in setXMLNodeText
Verfasst: 30.03.2022 20:17
von STARGÅTE
Hast du es mal mit #CRLF$ probiert?
Code: Alles auswählen
SetXMLNodeText(*Node, "Text Zeile1"+#CRLF$+"Text Zeile2")
Das Sonderzeichen umgewandelt werden ist glaube ich nicht zu verhindern.
Damit wird in jedem Fall immer ein Valider XML Code erzeugt.
Soll heißen, der Text darf nicht den XML-Tree zerstören.
Re: XML - Ampersand (&) in setXMLNodeText
Verfasst: 30.03.2022 20:35
von ThorKonnat
@TroaX: ja, ich verwende die XML Standardcodierung UTF8.
Wenn ich " " eingebe, bekomme ich "&#10;"
Wenn ich &#10;" eingebe, bekomme ich "&amp;#10;" Das & wird sofort durch & ersetzt.
@STARGÅTE : Sowohl #LF$ als auch #CRLF$ als auch \n erzeugen wunderschöne Zeilenumbrüche in der XML Datei.
Leider ersetzt EXCEL diese duch Leerzeichen.
Re: XML - Ampersand (&) in setXMLNodeText
Verfasst: 31.03.2022 05:30
von Pelagio
Guten Morgen,
es ist notwendig die Zelle auf Textumbruch zu formatieren (Zelle formatieren|Ausrichtung|Textumbruch).
Beispiel ' ="Text1" & ZEICHEN(10) & "Text2" '
Wird Textumbruch nicht gekennzeichnet: Text1Text2
Bei Kennzeichnung vom Textumbuch:
Text1
Text2
Im Augenblick bin ich noch etwas zu müd um einen entsprechenden Code zu posten aber ich hoffe, glaube
das meine Info weiterhelfen wird, kann.
Re: XML - Ampersand (&) in setXMLNodeText
Verfasst: 31.03.2022 08:32
von ThorKonnat
Hallo Pellagio,
Du bist jetzt auf der EXCEL Seite?
In der spreadsheetML Datei sind die EXCEL Felder über <styles> definiert:
<Style ss:ID="S1" ss:Name="Default">
<Alignment ss:Vertical="Center" ss:WrapText="1"/>
<Font ss:FontName="Calibri" ss:Size="10" ss:Color="#000000"/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
ss:WrapText="1" schaltet den Zeilenumbruch ein.
Das ist allerdings der automatische Zeilenumbruch, wenn der Text zu lang ist.
Ich möchte den Zellentext an einer von mir definierten Stelle umbrechen, als wenn ich in EXCEL ALT-ENTER drücke.
Dieser Umbruch wird in der spreadsheetML Datei mit " " erzeugt.
Ich bin das Problem jetzt umgangen, indem ich eine bestimmte Zeichenfolge "\\" in die XML einfüge, die XML dann in ein Editorfenster lade und dort gegen " " tausche. So habe ich auch gleich eine Kontrollmöglichkeit.
Dann speichere ich den Inhalt mit CreateFile /WriteString / CloseFile und schon macht EXCEL, was ich will.
<Cell ss:MergeAcross="1" ss:StyleID="S1">
<Data ss:Type="String">Text1 Text2</Data>
</Cell>
Vielen Dank für Eure Unterstützung!
Re: XML - Ampersand (&) in setXMLNodeText
Verfasst: 02.04.2022 22:57
von helpy
@ThorKonat: Es gibt eine Lösung. Du musst CDATA verwenden.
Hier ein Code-Ausschnitt:
Code: Alles auswählen
SetXMLNodeText(nData, "Das ist eine Zellemit Zeilenumbruch.")
nCDATA = CreateXMLNode(nData, "#cdata", #Null, #PB_XML_CData)
SetXMLNodeText(nCDATA, #LF$)
SetXMLNodeOffset(nCDATA, 18)
Re: XML - Ampersand (&) in setXMLNodeText
Verfasst: 15.04.2022 17:00
von ThorKonnat
Hallo helpy,
leider funktioniet CData als Nodetyp nicht, da ein solcher Node keine Attribute haben darf. Es kommt eine Fehlermeldung...
EXCEL erwartet aber dasAtribut ss:Type.
<Data ss:Type="String">Text Zeile1 Text Zeile2</Data>
Grüße
Re: XML - Ampersand (&) in setXMLNodeText
Verfasst: 15.04.2022 17:25
von helpy
Ich meinte auch nicht, dass CDATA anstatt Data verwendet wird!
Es funktioniert, wenn Du Data-Knoten mit Attribut ss:Type verwendest und CDATA als Kindknoten einfügst. Innerhalb von CDATA dann nicht das Entity einfügen sondern chr(10) ...
Re: XML - Ampersand (&) in setXMLNodeText
Verfasst: 15.04.2022 22:15
von helpy
Und hier ein Testcode, der eine XML-Datei aus der DataSection lädt, die zwei vorhandenen Zellen füllt mit Text, der jeweils einen Zeilenumbruch enthält:
Code: Alles auswählen
EnableExplicit
Procedure CellSetString(nCell, text.s)
Protected nData, nCDATA
nData = CreateXMLNode(nCell, "Data")
SetXMLAttribute(nData, "ss:Type", "String")
nCDATA = CreateXMLNode(nData, "#cdata", #Null, #PB_XML_CData)
SetXMLNodeText(nCDATA, text)
EndProcedure
Define sXML.s, xml, nRoot
Define nRow, nCell
Define cntCell
Restore ExcelXML_START
Read.s sXML
xml = ParseXML(#PB_Any, sXML)
If xml
If XMLStatus(xml) = #PB_XML_Success
Debug "XML loaded succesfully: " + Str(xml)
nRoot = RootXMLNode(xml)
nRow = XMLNodeFromPath(nRoot, "/Workbook/Worksheet/Table/Row")
nCell = ChildXMLNode(nRow)
While nCell
cntCell + 1
CellSetString(nCell,
"Zelle in Spalte " + Str(cntCell) + "." +
#LF$ + "Zweite Zeile!" )
nCell = NextXMLNode(nCell)
Wend
SaveXML(xml, GetPathPart(ProgramFilename()) + "test.xml")
FreeXML(xml)
Else
Debug XMLError(xml) + " in line " + Str(XMLErrorLine(xml)) + " at position " + Str(XMLErrorPosition(xml))
EndIf
Else
Debug "Could not load xml from data section."
EndIf
DataSection
ExcelXML_START:
Data.s ~"<?xml version=\"1.0\"?>\r\n" +
~"<?mso-application progid=\"Excel.Sheet\"?>\r\n" +
~"<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" +
~" xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n" +
~" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\r\n" +
~" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" +
~" xmlns:html=\"http://www.w3.org/TR/REC-html40\">\r\n" +
~" <Styles>\r\n" +
~" <Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n" +
~" <Alignment ss:Vertical=\"Top\"/>\r\n" +
~" <Font ss:FontName=\"Calibri\" x:Family=\"Swiss\" ss:Size=\"12\" ss:Color=\"#000000\"/>\r\n" +
~" </Style>\r\n" +
~" <Style ss:ID=\"wrapText\">\r\n" +
~" <Alignment ss:Vertical=\"Top\" ss:WrapText=\"1\"/>\r\n" +
~" </Style>\r\n" +
~" </Styles>\r\n" +
~" <Worksheet ss:Name=\"Tabelle1\">\r\n" +
~" <Table ss:ExpandedColumnCount=\"2\" ss:ExpandedRowCount=\"1\" x:FullColumns=\"1\"\r\n" +
~" x:FullRows=\"1\" ss:DefaultColumnWidth=\"60\" ss:DefaultRowHeight=\"15\">\r\n" +
~" <Column ss:AutoFitWidth=\"0\" ss:Width=\"150\"/>\r\n" +
~" <Column ss:AutoFitWidth=\"0\" ss:Width=\"150\"/>\r\n" +
~" <Row ss:Height=\"32\">\r\n" +
~" <Cell ss:StyleID=\"wrapText\"></Cell>\r\n" +
~" <Cell ss:StyleID=\"wrapText\"></Cell>\r\n" +
~" </Row>\r\n" +
~" </Table>\r\n" +
~" </Worksheet>\r\n" +
~"</Workbook>"
ExcelXML_END:
EndDataSection
Wenn ich die XML-Datei text.xml mit Excel (2016) öffne, dann wird der Text an der korrekten Stelle umgebrochen!